.NET Framework 4.7.1上で実行されているASP.NET MVC 5 Webアプリケーションがあります。私たちは時々そうのような新しいTask
を開始し、サービスのメソッドを呼び出すコントローラのアクションインサイドタスクの完了後にASP.NET MVCアプリケーションが応答しなくなる
:
コントローラ:(Global.asax
内部static
オブジェクトとして存在)
public async Task<ActionResult> Index()
{
Info info = await this.someService.GetInformationAsync().ConfigureAwait(false);
return this.ProcessInfo(info);
}
がSomeService:
private readonly Object taskLock = new Object();
private Task errorCheckerTask;
public Task<Info> GetInformationAsync()
{
try
{
...
}
catch(Exception ex)
{
this.StartErrorChecker();
}
return null;
}
private void StartErrorChecker()
{
lock(this.taskLock)
{
if(this.errorCheckerTask == null || this.errorCheckerTask.Status >= TaskStatus.RanToCompletion)
{
this.errorCheckerTask = this.BeginErrorCheckerAsync(CancellationToken.None);
}
}
}
private async Task BeginErrorCheckerAsync(CancellationToken ct)
{
while(!ct.IsCancellationRequested)
{
Boolean ok = await DoStuff();
if(ok) return;
await Task.Delay(30 * 1000).ConfigureAwait(false);
}
}
BeginErrorCheckerAsync
タスクが初めて開始された後は、 BeginErrorCheckerAsync
が2回目に実行されると、Visual StudioのOutput
ウィンドウにスレッドの束が終了し、Webアプリケーションが新しいHTTP要求に応答しなくなるというレポートが表示されます。すべてのブラウザはリクエストを送信した後で応答を待っていると言います。
ブレークボタンを押すと、Visual Studioの[スレッド]ウィンドウには実行中のスレッドがわずかしか表示されず、スタックトレースにユーザーコードが含まれていませんでした。
スレッド0x5440はコード0(0x0の)で終了しました:
重要なのは、何の初回例外は発生していないか、異常な出力は、スレッドについてのメッセージのほかに出力]ウィンドウに表示されていました。 スレッド0x547cがコード0(0x0)で終了しました。 スレッド0x5450がコード0(0x0)で終了しました。 スレッド0x5474がコード0(0x0)で終了しました。
私はASP.NET MVCのバグを発見していないと仮定しています - (それが問題だと仮定)が、私はタスク/ async
/await
の私の使用は、ASP.NETのデッドロックを作ることができる方法を理解していません。私のコードにはどこでも、私はtask.Result
またはtask.Wait()
と呼ばれ、従来の形式のasync/awaitデッドロックは除外されていますが、スレッドスタックトレースは.NETコードにはありません。
質問に「DoStuff」のコードを含めていないので、[MCVE](https://stackoverflow.com/help/mcve)はありません。さらに、例外処理のために複雑なプロセスがある理由は明確ではありません。 – mason