我在论坛中发现了一些关于此错误的例子,但我显然没有技术知识可以让我的案例真正“异步”#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优雅地给客户端带来了良好的结果,客户端继续进行下一个任务,一切都很好,服务器上这个容易出错的调用成功完成了它的任务(无论是成功与否对客户端无关紧要 - 这就是为什么它被作为一个后期操作任务进行线程化。)