gpt4 book ai didi

asp.net - 在 IHttpAsyncHandler 中使用 Task 或 async/await

转载 作者:行者123 更新时间:2023-12-02 09:20:27 31 4
gpt4 key购买 nike

自从开始编写 ASP.NET 应用程序时,当我想添加线程时,我可以通过 3 种简单的方法在 ASP.NET 应用程序中完成线程:

  • 使用System.Threading.ThreadPool
  • 使用自定义委托(delegate)并调用其 BeginInvoke 方法。
  • 借助 System.Threading.Thread 类使用自定义线程。

前两种方法提供了一种为应用程序启动工作线程的快速方法。但不幸的是,它们会损害应用程序的整体性能,因为它们消耗来自 ASP.NET 用来处理 HTTP 请求的同一池中的线程

然后我想使用一个新的Task或者async/await来编写IHttpAsyncHandler。您可以找到 Drew Marsh 在这里解释的一个示例:https://stackoverflow.com/a/6389323/261950

我的猜测是,使用 Task 或 async/await 仍然会消耗 ASP.NET 线程池中的线程,而且我不希望这样做,原因很明显。

您能否告诉我我是否可以在后台线程上使用任务(异步/等待),就像使用 System.Threading.Thread而不是来自线程池

预先感谢您的帮助。

托马斯

最佳答案

这种情况是 Taskasyncawait 真正发挥作用的地方。下面是同一个示例,经过重构以充分利用 async(它还使用我的 AsyncEx 库中的一些辅助类来清理映射代码):

// First, a base class that takes care of the Task -> IAsyncResult mapping.
// In .NET 4.5, you would use HttpTaskAsyncHandler instead.
public abstract class HttpAsyncHandlerBase : IHttpAsyncHandler
{
public abstract Task ProcessRequestAsync(HttpContext context);

IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var task = ProcessRequestAsync(context);
return Nito.AsyncEx.AsyncFactory.ToBegin(task, cb, extraData);
}

void EndProcessRequest(IAsyncResult result)
{
Nito.AsyncEx.AsyncFactory.ToEnd(result);
}

void ProcessRequest(HttpContext context)
{
EndProcessRequest(BeginProcessRequest(context, null, null));
}

public virtual bool IsReusable
{
get { return true; }
}
}

// Now, our (async) Task implementation
public class MyAsyncHandler : HttpAsyncHandlerBase
{
public override async Task ProcessRequestAsync(HttpContext context)
{
using (var webClient = new WebClient())
{
var data = await webClient.DownloadDataTaskAsync("http://my resource");
context.Response.ContentType = "text/xml";
context.Response.OutputStream.Write(data, 0, data.Length);
}
}
}

(如代码中所述,.NET 4.5 有一个 HttpTaskAsyncHandler ,与上面的 HttpAsyncHandlerBase 类似)。

关于异步真正酷的一点是,它在执行后台操作时不占用任何线程:

  • ASP.NET 请求线程启动请求,并开始使用 WebClient 下载。
  • 在下载过程中,await 实际上从 async 方法返回,离开请求线程。该请求线程将返回到线程池 - 留下 0()个线程来服务该请求。
  • 下载完成后,async 方法将在请求线程上恢复。该请求线程仅用于编写实际响应。

这是最佳线程解决方案(因为需要请求线程来写入响应)。

原始示例也以最佳方式使用线程 - 就线程而言,它与基于async的代码相同。但在我看来,async 代码更容易阅读。

如果您想了解有关异步的更多信息,我有一个 intro post在我的博客上。

关于asp.net - 在 IHttpAsyncHandler 中使用 Task 或 async/await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9225420/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com