4

awaitステートメントの後にコントローラーが破棄されるのはなぜですか?

    public async Task<ViewResult> MyAction()
    {
            await Task.Yield();

            // controller disposed at this point... why?

            return this.View();
    }

私のコントローラーは、メソッドをオーバーライドして破棄するリソースを使用していますDispose...しかし、async/awaitを使用すると、awaitステートメントが実行されるとすぐにコントローラーが破棄されるため、これが壊れているようです...非同期の方法でリソースを破棄するにはどうすればよいですか/await はサポートされていますか?

編集: dispose メソッドのコールスタックの最後のメソッド:

MyWebRole.dll!MyWebRole.Code.MyController.Dispose(bool disposing = true) Line 102   C#
System.Web.Mvc.dll!System.Web.Mvc.Controller.Dispose() + 0x25 bytes   
System.Web.Mvc.dll!System.Web.Mvc.DefaultControllerFactory.ReleaseController(System.Web.Mvc.IController controller = {MyWebRole.Areas.App.Controllers.LongPollingController}) + 0x3e bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.BeginProcessRequest.AnonymousMethod__5() + 0x70 bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.MakeVoidDelegate.AnonymousMethod__0() + 0x2d bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.BeginSynchronous<System.Web.Mvc.Async.AsyncVoid>.AnonymousMethod__7(System.IAsyncResult _ = {System.Web.Mvc.Async.SimpleAsyncResult}) + 0x2b bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>.End() + 0x99 bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.End<System.Web.Mvc.Async.AsyncVoid>(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}, object tag = {object}) + 0x3c bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.End(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}, object tag = {object}) + 0x29 bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.EndProcessRequest.AnonymousMethod__d() + 0x27 bytes   
System.Web.Mvc.dll!System.Web.Mvc.SecurityUtil.GetCallInAppTrustThunk.AnonymousMethod__0(System.Action f = {Method = {System.Reflection.RuntimeMethodInfo}}) + 0x20 bytes   
System.Web.Mvc.dll!System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(System.Action action = {Method = {System.Reflection.RuntimeMethodInfo}}) + 0x3e bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.EndProcessRequest(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}) + 0x77 bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(System.IAsyncResult result = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}) + 0x27 bytes   

Disposeメソッドが呼び出されています...それはdisposing = true悪いです。多分バグ?

EDIT 2:サブクラス化を試みましAsyncControllerたが、同じことが起こります。

回避策はありますか?

4

3 に答える 3

6

質問に示されているコール スタックは、MVC4 ではなく MVC3 のものです。Task残念ながら、MVC3 はベースの非同期呼び出しをサポートしていません。await を呼び出すと、タスクが開始される可能性がありますが、MVC3 はそれについて何も知らないため、それを呼び出しToString()ContentResult.

ベースのTask非同期サポートは MVC4 で追加され、実際には から派生する必要さえありませんAsyncController。MVC4のすべてControllersが同期とTaskベースの非同期をサポートしています。AsyncControllerAsync/Completed パターンを使用する場合にのみ必要です。

于 2013-03-22T05:43:07.387 に答える
0

スタック トレースに基づいて、プロセス要求を開始したものは何でも終了することを決定したため、コントローラーへの参照が失われ、ガベージ コレクション/破棄の対象となります。プロセス要求を開始した理由と、それが終了する理由を調べます。

于 2013-03-22T03:52:02.313 に答える
0

私はこの問題を抱えていて、丸一日悩みました。ControllerFactory に接続していた ActionInvoker が ControllerActionInvoker から継承されていることに最終的に気付きました。それを AsyncControllerActionInvoker に変更すると、問題はなくなりました。

于 2015-05-21T02:32:42.633 に答える