web-dev-qa-db-ja.com

C#で待機せずに非同期を使用していますか?

awaitなしでasyncを使用する を検討してください。

多分あなたは非同期が何をするかを誤解していると思います。警告は正確です。メソッドを非同期としてマークし、どこでもawaitを使用しない場合、メソッドは非同期になりません。呼び出すと、メソッド内のすべてのコードが同期的に実行されます。

私は非同期を実行する必要がありますが、スレッドを使用する場合はawait.forを使用する必要がないメソッドを書きたいです

public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}

PushCallAsyncを呼び出してasyncを実行し、awaitを使用したくない。

C#で待つことなく非同期を使用できますか?

27
user1968030

もしあなたの Logger.LogInfoはすでに非同期です。これで十分です:

public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}

待機せずに非同期で開始するだけではない場合

public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));
}
28
Visions

あなたはまだasyncを誤解しています。 asyncキーワードはnotは「別のスレッドで実行」を意味します。

いくつかのコードを別のスレッドにプッシュするには、明示的に行う必要があります(例:Task.Run

await Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));

async/await紹介記事 があります。

24
Stephen Cleary

asyncを誤解しています。実際には、バックグラウンドで行う制御フローの反転を伝播するようコンパイラーに指示します。そのため、メソッドスタック全体が非同期としてマークされます。

あなたが実際に何をしたいのかはあなたの問題次第です。 (呼び出しLogger.LogInfo(..)は最終的にFile.WriteAsync()などを呼び出すので、asyncメソッドであると考えてみましょう。

  • Functionを呼び出すことがvoidイベントハンドラーである場合は、問題ありません。非同期呼び出しは、バックグラウンドである程度発生します(つまり、File.WriteAsync)。制御フローに結果は期待できません。それは火と忘れです。
  • ただし、結果を使用して何かを実行する場合、またはその場合にのみ続行する場合は、Logger.LogInfo(..)が完了したら、予防措置を講じる必要があります。これは、メソッドが何らかの理由での中間呼び出しスタックである場合です。その後、Logger.LogInfo(..)は通常Taskを返し、待機することができます。ただし、GUIスレッドをデッドロックするため、task.Wait()の呼び出しに注意してください。代わりにawaitを使用するか、タスクを返します(非同期を省略できます)。
public void PushCallAsync(CallNotificationInfo callNotificationInfo) 
{
   return Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId); 
}

または

 public async void PushCallAsync(CallNotificationInfo callNotificationInfo) 
 {
    await Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId); 
 }
6
Robetto

Logger.LogInfoが同期メソッドである場合、呼び出し全体はとにかく同期になります。必要なのが、別のスレッドでコードを実行することだけである場合、asyncはジョブのツールではありません。代わりにスレッドプールで試してください。

ThreadPool.QueueUserWorkItem( foo => PushCallAsync(callNotificationInfo) );
2
ya23