“ UseTaskFriendlySynchronizationContext”是什么意思?


68

asp.net 4.5中有一个新的应用程序设置

<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”是什么意思?

Answers:


74

关于UseTaskFriendlySynchronizationContext,来自Microsoft论坛

这告诉ASP.NET使用全新的异步管道,该管道遵循CLR约定以启动异步操作,包括在必要时将线程返回到ThreadPool。ASP.NET 4.0及更低版本遵循其自己的约定,这与CLR准则背道而驰,如果未启用该开关,则 异步方法容易同步运行,死锁请求或以其他方式无法正常工作。

另外,我认为AsyncOperationManager是针对桌面应用程序的。对于您应该使用RegisterAsyncTask和设置的ASP.NET应用程序<%@ Page Async="true"请参见此处以获取更多详细信息

因此,使用新的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);
}

目的是通过发行版支持以下内容,但当前不支持Beta版:

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

我使用了目标代码,效果很好。如何知道当前不支持它?什么情况不支持?
推土机2012年

1
@Dozer,我猜您没有将UseTaskFriendlySynchronizationContext设置为true吗?我收到有关无法使用“响应”的错误(易于解决,但如果无法更改的控件被编码为可以访问它,则不会)。如果您通过该链接访问Microsoft论坛,则可以阅读有关我遇到的几个问题以及Microsoft员工不支持的评论。我得到的印象是由于问题(不知道是什么,但您可以在该论坛中询问),它不会自动插入RegisterAsyncTask中,如果不是这样,则无法获得同步运行的任何好处。
Michael

在MSDN中的回答是:“在您的特定示例中,使用异步void方法而不设置<appSettings>开关实际上会在您的Page中引入竞争条件,在这种情况下,不能保证在实际使用Page之前先调用DataBind()方法呈现并将其输出发送到客户端”。但是我尝试了一下,并且页面始终在DataBind()方法之后呈现。
推土机

删除<appSettings>后,我发现了一个问题。如果您编写两个方法:async Page_Load,async Button1_Click。当您单击按钮时,这两个方法将并行运行。我认为这种情况是“种族条件”。
推土机

13

有关MSDN上appSettings的ASP.NET 4.5.1文档,引用了更多详细信息:

aspnet:UseTaskFriendlySynchronizationContext

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

...

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.