2017-11-27 18 views
-1

長いタスクを実行するプログラムを作成しました。この作業では、 "await"コールを実行する必要がありますが、これをマルチスレッド化する方法はわかりません。これは私のコードです:C#で複数の非同期タスクを実行

ApplicationDbContext db = new ApplicationDbContext(); 
foreach (var apiaccount in db.APIAccounts.ToArray()) 
{ 
    var max = db.Chats.Where(a => a.apiaccountid == apiaccount.id).Max(a => a.ended); 
    var start = max != null ? max.Value : new DateTime(2014, 10, 1, 1, 0, 0); 

    if (start.Hour == 0) 
    { 
     start = start.AddDays(-1); 
    } 

    var mod = new ImportAPIModel() 
    { 
     email = apiaccount.Email, 
     token = apiaccount.Token, 
     startdate = start, 
     stopdate = null, 
     importid = importid, 
     apiaccountid = apiaccount.id 
    }; 

    await ImportAPI(mod); 
} 

//async Task ImportAPI(object obj) 

いくつかのアカウントしかありませんので、私はコードを隣り合わせで開始します。だから私はコードを変更する:

ApplicationDbContext db = new ApplicationDbContext(); 
List<Thread> threads = new List<Thread>(); 

foreach (var apiaccount in db.APIAccounts.ToArray()) 
{ 
    var max = db.Chats.Where(a => a.apiaccountid == apiaccount.id).Max(a => a.ended); 

    var start = max != null ? max.Value : new DateTime(2014, 10, 1, 1, 0, 0); 
    if (start.Hour == 0) 
    { 
     start = start.AddDays(-1); 
    } 

    var mod = new ImportAPIModel() 
    { 
     email = apiaccount.Email, 
     token = apiaccount.Token, 
     startdate = start, 
     stopdate = null, 
     importid = importid, 
     apiaccountid = apiaccount.id 
    }; 

    //await ImportAPI(mod); 

    Thread thread = new Thread(new ParameterizedThreadStart(ImportAPI)); 
    thread.Start(mod); 

    threads.Add(thread); 
} 

foreach (var thread in threads) thread.Join(); 

//async Task ImportAPI(object obj) 

しかし、これはスレッドがタスクの種類を使用することはできませんので、コンパイルされません。私はそれを無効に変更すると実行されますが、.Join()コマンドで待機しません。

これは非同期プログラミングでは本当に簡単なはずです。私はgoogleでこれについていくつかの情報を見つけようとしましたが、結果はありません。だからこれが私が求めている理由です。私は重複してタグ付けされないことを願っていますが、もしそうなら、私はとにかく助けになるでしょう:) Stackoverflowが最高です。

+1

ところで、DbContextオブジェクトにusingブロックを使用して自動的に破棄することをお勧めします。今すぐ手動で処分する必要があります。 –

+0

これは本当ですか?スレッドは関数を終了し、gabageコレクタはdatacontextを正しく受け取りますか? – ikwillem

+1

ガベージコレクタを信頼するべきではありません。メモリ不足のプログラムの場合、完全なガーベッジコレクションはプログラムの寿命を通して決して実行されない可能性があります。 –

答えて

0

ImportAPIから生成されたタスクをTask.WhenAllawaitと呼ぶよりもリストに追加してください。リスト内のすべてのタスクが完了すると完了する新しいタスクが返されます。

var tasks = new List<Task<SomeType>>(); 
foreach (var apiaccount in db.APIAccounts.ToArray()) 
{ 
    .... 
    tasks.Add(ImportAPI(mod)); 
} 
await Task.WhenAll(tasks); 
関連する問題