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
Task
Task<TResult>
async
これでawait
、Task
以下のようなものを実行できます。await
なしでは使用できませんasync
。
await Task.Run(() => MethodWithParameter(param));
したがって、一般にawait
、タスクを実行する場合、渡されたパラメーターを潜在的に共有されるリソースとして扱うことを回避でき、複数のスレッドから何かを一度に変更することのすべての落とし穴があります。また、クロージャに注意してください。それらについては詳しく説明しませんが、リンクされた記事はそれをうまくやってくれます。
サイドノート
少し外れたトピックですが、WinForms GUIスレッドでは、でマークされているため、あらゆるタイプの「ブロック」を使用する場合は注意が必要[STAThread]
です。を使用してawait
もまったくブロックされませんが、ある種のブロックと組み合わせて使用されることがあります。
WinForms GUIスレッドを技術的にブロックできないため、「ブロック」は引用符で囲んでいます。はい、あなたが使用している場合lock
WinFormsのGUI上で、それはスレッドうまだそれがの「ブロック」を考え、あなたにもかかわらず、メッセージをポンプ。そうではありません。
これは、非常にまれなケースで奇妙な問題を引き起こす可能性があります。lock
たとえば、ペイントするときにを使用したくない理由の1つ。しかし、それはフリンジで複雑なケースです。しかし、私はそれがクレイジーな問題を引き起こすのを見てきました。だから私は完全を期すためにそれを書き留めました。