お世話になります。
Taskを使用した非同期処理で解決できない現象があり、質問させて頂きます。
非同期処理をする目的は、フォームのフリーズを防ぐため、複数のデータ作成処理を並行して行いたいためです。
1.ソリューション内にプロジェクト Main, A があります。
2.Mainプロジェクトのフォーム操作からのイベントから、Aプロジェクト内のclass_AクラスのMainメソッドを呼び出しています。
3.class_AクラスのMainメソッドでループ処理をし、その中でMakeDataメソッドを呼び出しています。
4.サンプルソースにはAデータを作るタスクしか書いてありませんが、実際には複数のタスクがあり、
WhenAll(task_A, task_B, task_C, ...) という形になりますが、テストでtask_Aだけにしていますが、1つだけでも問題が起きています。
ソース
Mainプロジェクト
C#
1private async void A_Load() 2{ 3 class_A cls_A = new cls_A(); 4 await Task.Run(async() => 5 { 6 await cls_A.Main(); 7 }); 8}
Aプロジェクト class_A.cs
C#
1public async Task<bool> Main() 2{ 3 for(int i = 0; i < 100; i++) 4 { 5 if(await MakeData(i) == false) 6 { 7 return false; 8 } 9 } 10 return true; 11} 12 13private async Task<bool> MakeData(int i) 14{ 15 Task task_A = Task.Run(() => 16 { 17 clsCreateData_A Create_A = new clsCreateData_A(); 18 int Count_A = 0; 19 string strCreateData_A = Create_A.CreateData_A(i, ref Count_A); 20 if(strCreateData_A == "") 21 { 22 Console.Writeline("Aデータ:" + Count_A.ToString() + "件"); 23 } 24 else 25 { 26 //エラー処理 27 reutrn false; 28 } 29 }); 30 31 await Task.WhenAll(task_A); 32 33 return true; 34}
Aプロジェクト clsCreateData_A.cs
C#
1public string CreateData_A(i, ref Count) 2{ 3 return ""; 4 5 //実際には下にコードが続きますが試験的に止めてすぐreturnを返すようにしています。 6 //これでも問題は発生しています。 7}
このような処理で、await Task.WhenAll(task_A); から先に進まずに止まってしまいます。
確認したこと
1.CreateData_Aの中身が関係しているのか確認するために、すぐreturnを返すようにしましたがTask.WhenAllで止まってしまいます。
C#
1Task Task_A = Task.Run(() => 2{ 3 Console.WriteLine("AAA") 4} 5await Task.WhenAll(Task_A);
2.上記のようにしてTask内での別クラス呼び出しを止めて簡単なコードにしたところ、問題なく進みました。
3.Task.WhenAllの代わりにTask_A.Wait(); とすると、問題なく進みました。
4.await Task.WhenAll(Task_A) をawait Task.WaitAll(Task_A) に変えると、CS4008 'void'を待機することができません というエラーが発生します。
await を外して Taks.WaitAllとすると、フォームもフリーズせず臨んだ通りの動作をしますが、
CS1998 この非同期メソッドには'await'演算子がないため~ という警告が出ています。
await を使っていないので、MakeDataメソッドの async を外すと、return のところで
CS0029 型 'bool' を 'System.Threading.Tasks.Task<bool>' に暗黙的に変換できません
というエラーが発生します。
async がない場合の Task<bool> の返り値にはどのように返せばよいのか、調べても理解できませんでした。
エラー、警告が無く動作するようにはどうしたら良いか、アドバイスが欲しいです。
Taskについての知識も浅いので、もっと良い書き方もあるかと思います。
よろしくお願い致します。
回答1件
あなたの回答
tips
プレビュー