質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

解決済

2回答

1073閲覧

UWPのファイルリード非同期制御がうまくできない

退会済みユーザー

退会済みユーザー

総合スコア0

UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2019/03/04 09:15

編集2019/03/05 03:57

UWPアプリケーションで、CSVファイルをリードして画像のパスを取得し、その画像ファイルを指定のフォルダにコピーする処理を行うアプリケーションを作成しています。

UWPの場合、ファイル処理にFileStreamなどを使用する方法ではうまくいかなかったため、StorageFileクラスを用いたファイル処理を行うことにより関数を実装しています。
しかし、StorageFile関数が非同期処理のため、それを用いるメソッドも非同期で作成されることになります。

現状、下記のような関数を作成しています

Read関数

C#

1public async Task Read(StorageFile file) 2{ 3 var buff = FileIO.ReadBufferAsync(file); 4 Encoding.Registerprovider(CodePagesEncodingProvider.Instance); 5 var enc = Encoding.GetEncoding("Shift_JIS"); 6 lines = enc.GetString(buff.ToArray()).Split('\n'); 7 (CSVからファイル名を取り出す処理) 8}

CopyFile関数

C#

1public async Task<bool> CopyFile() 2{ 3 foreach (ファイルの数だけ繰り返す) 4 { 5 inputFile = await StorageFile.GetFileFromPathAsync(入力ファイル名); 6 targetFolder = await StorageFolder.GetFolderFromPathAsync(出力先); 7 8 try 9 { 10 出力ファイル = await inputFile.CopyAsync(targetFolder); 11 } 12 catch (Exception) 13 { 14 ret = false; 15 } 16 } 17 return ret; 18}

ReadとCopyFileの呼び出し

C#

1private async Task<bool> ReadFile(StorageFile file) 2{ 3 bool ret; 4 Task task = Read(file); 5 task.Wait(); // これを入れるとReadの処理から戻らない。入れないと後のCopyFileがReadを待たずに実行される。 6 await CopyFile(); 7 return true; 8}

この状態でやりたいことはRead関数の呼び出しの後、CopyFileを呼び出したいのですが、非同期処理のためCopyFileがReadの終了を待たずに実行されます。

taskのWaitでReadの実行を待つという方法を試みましたが、Waitに入ったまま戻らなくなりました。

うまい処理方法はあるでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

非同期メソッド入門 (10) - WinRTとの相互運用

以下、一例として戻り値を持つ非同期インターフェースであるIAsyncOperation<T>をTask<T>に変換する拡張メソッドを示します。

ReadBufferAsync の戻り値である IAsyncOperation<T> を Task に変換して await してみてはどうでしょうか?

投稿2019/03/05 00:24

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/05 00:55

ご回答ありがとうございます。 上記で書き忘れてましたが、ReadBufferAsyncは次のように使用しています。 var buff = await FileIO.ReadBufferAsync(file); そのあとの処理は Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var enc = Encoding.GetEncoding("Shift_JIS"); lines = enc.GetString(buff.ToArray()).Split('\n'); buffの戻り値は配列化して使用していますが、Taskに変換しても取り出すことはできるのでしょうか?
Zuishin

2019/03/05 01:33

Task<T> は T 型の戻り値を戻します。試してみてください。
退会済みユーザー

退会済みユーザー

2019/03/05 02:13

申し訳ありません。 試してみましたが、元の問題の解決にはなっていないようです。 ありがとうございました。
Zuishin

2019/03/05 02:15

どのように試したんですか?
退会済みユーザー

退会済みユーザー

2019/03/05 02:21

教えていただいたHPの中のAsTask<T>関数を追加し、ReadBufferAsyncの呼び出しのところにAsTask()を追加しました。 var buff = await FileIO.ReadBufferAsync(file).AsTask();
Zuishin

2019/03/05 02:32

その後にコピーできなかったということですか?
Zuishin

2019/03/05 02:34

ちょっと問題を読み間違っているのかもしれません。マークダウンを使い、起こる問題がもっと明確になるようエラーメッセージや結果などを追記して質問を編集してください。
退会済みユーザー

退会済みユーザー

2019/03/05 02:47

ありがとうございます。 Readの結果をもとにコピーする処理が行われていない(Readではコピーするファイルのパスを読み取る処理があり、そのデータを使ってCopyFileを行う)ということです。 エラーメッセージは出ません。 質問修正しましたので、もし何かわかることがございましたらよろしくお願いします。 お手数をおかけして申し訳ありません。
Zuishin

2019/03/05 02:54

コードが見にくいのでマークダウンのコードブロックを使ってください。 Task.Wait の代わりに await を使ってもダメという意味ですか?
退会済みユーザー

退会済みユーザー

2019/03/05 04:04

ご回答ありがとうございます。 awaitを使ったらコピー処理が行われました。 ベストアンサーとさせていただきます。
guest

0

ファイルのコピーするだけならそれ用の専用関数が用意されてますが、(System.IO.File以下の関数群)これではダメなんでしょうか
また、FileStreamが使えないというのはどういう事情で使えないんでしょうか。

投稿2019/03/04 11:32

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/05 00:16

ご回答ありがとうございます。 System.IO.Fileの関数群はUWPでは使用できないです。 実際、「Synchronous operations should not be performed on the UI thread. Consider wrapping this method in Task.Run」という例外が発生します。 FileStreamは調査したら使用できる(StreamWriterやStreamReaderが使用できる方法がある)そうなので、ちょっと調べてみます。 参考 https://www.atmarkit.co.jp/ait/articles/1506/17/news027.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問