private void RunAsync()
{
string param = "Hi";
Task.Run(() => MethodWithParameter(param));
}
private void MethodWithParameter(string param)
{
}
編集
一般的な需要があるため、Task起動は呼び出しスレッドと並行して実行されることに注意する必要があります。デフォルトを想定すると、TaskSchedulerこれは.NETを使用しますThreadPool。とにかく、これはTask、一度に複数のスレッドによってアクセスされる可能性があるとして渡されるパラメータを考慮し、それらを共有状態にする必要があることを意味します。これには、呼び出し元のスレッドでそれらにアクセスすることも含まれます。
私の上記のコードでは、そのケースは完全に議論の余地があります。文字列は不変です。だから私はそれらを例として使用しました。しかし、あなたが使用していないと言うString...
一つの解決策は、使用することですasyncとawait。これは、デフォルトSynchronizationContextで、呼び出し元のスレッドをキャプチャし、の呼び出し後にメソッドの残りの部分の継続を作成awaitし、作成されたにアタッチしTaskます。このメソッドがWinFormsGUIスレッドで実行されている場合は、次のタイプになります。WindowsFormsSynchronizationContext。
継続は、キャプチャにポストバックされた後に実行SynchronizationContextされます-これもデフォルトでのみです。したがって、await呼び出し後に開始したスレッドに戻ります。これは、特にを使用して、さまざまな方法で変更できますConfigureAwait。要するに、そのメソッドの残りの部分はまで続行されません後Task、別のスレッドで完了しました。ただし、呼び出し元のスレッドは、メソッドの残りの部分ではなく、引き続き並行して実行されます。
メソッドの残りの実行が完了するのを待つことは、望ましい場合と望ましくない場合があります。そのメソッドの何も後で渡されたパラメータにアクセスしTaskない場合はawait、まったく使用したくない場合があります。
または、メソッドの後半でこれらのパラメータを使用する場合もあります。await安全に作業を続けることができるので、すぐに行う理由はありません。同じメソッドでも、Task返された変数をawait後で変数に格納できることを忘れないでください。たとえば、他の作業を行った後、渡されたパラメータに安全にアクセスする必要がある場合などです。ここでも、あなたはないではないに必要awaitにTask実行するとき右側に配置する。
とにかく、渡されたパラメータに関してこのスレッドセーフにする簡単な方法は、これTask.Runを行うことです。
最初飾る必要がありますRunAsyncとasync:
private async void RunAsync()
重要な注意点
リンクされたドキュメントに記載されているように、マークされたメソッドはvoidを返さないことが望ましいです。これに対する一般的な例外は、ボタンクリックなどのイベントハンドラーです。それらはvoidを返さなければなりません。それ以外の場合は、を使用するときに常にまたはを返そうとします。かなりの数の理由から、これは良い習慣です。async TaskTask<TResult>async
これでawait、Task以下のようなものを実行できます。awaitなしでは使用できませんasync。
await Task.Run(() => MethodWithParameter(param));
したがって、一般にawait、タスクを実行する場合、渡されたパラメーターを潜在的に共有されるリソースとして扱うことを回避でき、複数のスレッドから何かを一度に変更することのすべての落とし穴があります。また、クロージャに注意してください。それらについては詳しく説明しませんが、リンクされた記事はそれをうまくやってくれます。
サイドノート
少し外れたトピックですが、WinForms GUIスレッドでは、でマークされているため、あらゆるタイプの「ブロック」を使用する場合は注意が必要[STAThread]です。を使用してawaitもまったくブロックされませんが、ある種のブロックと組み合わせて使用されることがあります。
WinForms GUIスレッドを技術的にブロックできないため、「ブロック」は引用符で囲んでいます。はい、あなたが使用している場合lockWinFormsのGUI上で、それはスレッドうまだそれがの「ブロック」を考え、あなたにもかかわらず、メッセージをポンプ。そうではありません。
これは、非常にまれなケースで奇妙な問題を引き起こす可能性があります。lockたとえば、ペイントするときにを使用したくない理由の1つ。しかし、それはフリンジで複雑なケースです。しかし、私はそれがクレイジーな問題を引き起こすのを見てきました。だから私は完全を期すためにそれを書き留めました。