IIS正在抛出HTML页面错误,说“#34;无法启动异步操作..."

时间:2017-08-30 13:25:53

标签: c# asp.net asynchronous iis async-await

我在论坛中发现了一些关于此错误的例子,但我显然没有技术知识可以让我的案例真正“异步”#39; - 如果这是问题。

捕获时的错误是:

  

此时无法启动异步操作。异步   操作只能在异步处理程序中启动或   模块或在页面生命周期中的某些事件期间。如果这   执行页面时发生异常,确保页面为   标记为<%@ Page Async =" true" %取代。此例外也可能表示   试图调用" async void"方法,通常是不受支持的   在ASP.NET请求处理中。相反,异步方法   应该返回一个Task,调用者应该等待它。

     

在System.Web.AspNetSynchronizationContext.OperationStarted()at   System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()at   myCompany.System.Turhh.Turhh<> c__DisplayClass18_0.b__1(对象   发件人,GetInfoCompletedEventArgs e)at   myCompany.System.TurhhWebServices.InfoServiceClient.OnGetInfoCompleted(对象   状态)

代码:

public void GetInfoAsync(GetInfoRq request, object Infotate)
{
    if ((this.onBeginGetInfoDelegate == null))
    {
        this.onBeginGetInfoDelegate = new BeginOperationDelegate(this.OnBeginGetInfo);
    }
    if ((this.onEndGetInfoDelegate == null))
    {
        this.onEndGetInfoDelegate = new EndOperationDelegate(this.OnEndGetInfo);
    }
    if ((this.onGetInfoCompletedDelegate == null))
    {
        this.onGetInfoCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnGetInfoCompleted);
    }
    base.InvokeAsync(this.onBeginGetInfoDelegate, new object[] {
                request}, this.onEndGetInfoDelegate, this.onGetInfoCompletedDelegate, Infotate);
}


private BeginOperationDelegate onBeginGetInfoDelegate;
private EndOperationDelegate onEndGetInfoDelegate;
private System.Threading.SendOrPostCallback onGetInfoCompletedDelegate;

public event System.EventHandler<GetInfoCompletedEventArgs> GetInfoCompleted;

public System.IAsyncResult BeginGetInfo(GetInfoRq request, System.AsyncCallback callback, object asyncState)
{
    return base.Channel.BeginGetInfo(request, callback, asyncState);
}

public GetInfoRs EndGetInfo(System.IAsyncResult result)
{
    return base.Channel.EndGetInfo(result);
}

private System.IAsyncResult OnBeginGetInfo(object[] inValues, System.AsyncCallback callback, object asyncState)
{
    return this.BeginGetInfo(rq, callback, asyncState);
}

private object[] OnEndGetInfo(System.IAsyncResult result)
{
    GetInfoRs retVal = this.EndGetInfo(result);
    return new object[] {retVal};
}

private void OnGetInfoCompleted(object state)
{
    if ((this.GetInfoCompleted != null))
    {
        InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
        var ea = new GetInfoCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.Infotate);
        try
        {
            // Note: Encapsulating this in a Task.Run() hides the issue on the server (here)
            // but IIS still dumps its HTML page with an await/async error info.
            this.GetInfoCompleted(this, ea);
        }
        catch (InvalidOperationException ex)
        {
            // HELP:
            // Most of the time, this works fine. About 1 in 10 times, this exception is thrown.
            // When this exception is thrown (and caught), IIS still dumps its HTML async/await error
            System.Diagnostics.Debug.WriteLine(" **** AWAIT/ASYNC EXCEPTION 3 **** ");
        }
    }
}

这是GetInfoCompleted背后的代码:

channel.GetInfoCompleted += new EventHandler<GetInfoCompletedEventArgs>(async (sender, e) =>
{
    await complete(); // complete contains an 'await Task.Run(async() => { some server work here });' job
});

此异常仅在本地运行的10次中发生。在生产中,几乎每次都会发生。本质上,在非常快的服务器上,当异步调用同步而不是异步发生时,这会引发异常并激怒IIS,导致它将HTML错误页面转储到客户端。当这些调用是异步进行的,一段时间后,IIS优雅地给客户端带来了良好的结果,客户端继续进行下一个任务,一切都很好,服务器上这个容易出错的调用成功完成了它的任务(无论是成功与否对客户端无关紧要 - 这就是为什么它被作为一个后期操作任务进行线程化。)

0 个答案:

没有答案