2017-12-21 12 views
0

.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コードにはありません。

+2

質問に「DoStuff」のコードを含めていないので、[MCVE](https://stackoverflow.com/help/mcve)はありません。さらに、例外処理のために複雑なプロセスがある理由は明確ではありません。 – mason

答えて

0

コントローラーアクションメソッドでは、ConfigureAwait(false)は同期コンテキストで実行する必要があるため、呼び出すことはできません。

関連する問題