2012-03-05 244 views
57

有在asp.net一个新的应用程序设置4.5“UseTaskFriendlySynchronizationContext”的含义是什么?

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 

这样的代码可以在asp.net 4.0

protected void Button1_Click(object sender, EventArgs e) 
{ 
    CallAysnc(); 
} 

public void CallAysnc() 
{ 
    AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(Guid.NewGuid().ToString()); 

    WebClient client = new WebClient(); 
    client.DownloadStringCompleted += (object sender, DownloadStringCompletedEventArgs e) => 
    { 
     asyncOp.PostOperationCompleted(CallCompleted, e.Result); 
    }; 
    client.DownloadStringAsync(new Uri("http://www.google.com")); 
} 

private void CallCompleted(object args) 
{ 
    Response.Write(args.ToString()); 
} 

运行,但它不会在asp.net 4.5工作,当我删除新的appsetting,它再次工作!

那么“UseTaskFriendlySynchronizationContext”的含义是什么?

回答

62

关于UseTaskFriendlySynchronizationContext,从Microsoft Forums

这告诉ASP.NET使用一个全新的异步流水线其中 如下CLR约定开球异步操作, 包括在必要时返回线程的线程池。 ASP.NET 4.0及更低版本遵循自己的惯例,违背CLR准则,如果交换机未启用,则很容易使异步方法同步运行,死锁请求或以其他方式不按预期运行。

此外,我认为AsyncOperationManager是专门为桌面应用程序。对于ASP.NET应用程序,您应该使用RegisterAsyncTask并设置<%@ Page Async="true",see here for more details

因此,使用新的C#关键字的例子是:

protected void Button1_Click(object sender, EventArgs e) 
{ 
    RegisterAsyncTask(new PageAsyncTask(CallAysnc)); 
} 

private async Task CallAysnc() 
{ 
    var res = await new WebClient().DownloadStringTaskAsync("http://www.google.com"); 
    Response.Write(res); 
} 

的目的是支持由发布以下,但目前尚未在测试版支持:

protected async void Button1_Click(object sender, EventArgs e) 
{ 
    var res = await new WebClient().DownloadStringTaskAsync("http://www.google.com"); 
    Response.Write(res); 
} 
+0

我使用了目标代码,它工作正常。如何知道它目前不支持?什么情况不支持? – Dozer 2012-03-12 08:16:43

+1

@Dozer,我猜你没有UseTaskFriendlySynchronizationContext设置为true?我收到关于响应不可用的错误(易于解决,但如果您无法更改的控件编码为访问它,则不会)。如果您按照指向Microsoft论坛的链接,您可以阅读我遇到的几个问题以及Microsoft员工不支持的评论。我觉得它不会自动插入到RegisterAsyncTask,但由于问题(不知道是什么,但你可以在论坛上提问),如果没有,那么你将无法同步运行它。 – Michael 2012-03-12 10:24:42

+0

MSDN中的答案说:“在你的具体例子中,如果没有设置开关,实际上有一个异步void方法,实际上在页面中引入了一个竞争条件,其中DataBind()方法不能保证在页面实际呈现之前被调用并将其输出发送给客户端“。但是我试过了,页面总是在DataBind()方法之后呈现。 – Dozer 2012-03-13 09:47:42

7

更多细节,引用自MSDN的ASP.NET 4.5.1 documentation for appSettings

aspnet:UseTaskFriendl ySynchronizationContext

指定ASP.NET 4.5中异步代码路径的行为方式。

...

如果这个键值设置为false [默认],在ASP.NET 4.5异步代码路径的行为,因为他们在ASP.NET 4.0一样。如果此关键字 值设置为true,则ASP.NET 4.5会使用针对任务返回API优化 的代码路径。对于启用WebSocket的应用程序,设置此兼容性开关是 必需,在Web窗体页面中使用基于任务的 异步,以及某些其他异步 行为。