C# 将cpu绑定/io绑定的长时间运行代码包装到(异步)任务中
考虑简单的MVC5控制器:C# 将cpu绑定/io绑定的长时间运行代码包装到(异步)任务中,c#,multithreading,asynchronous,task-parallel-library,msmq,C#,Multithreading,Asynchronous,Task Parallel Library,Msmq,考虑简单的MVC5控制器: public class DocumentsController { // ctor code is omitted [HttpPost, Route("api/documents/request/stamp={stamp}")] public ActionResult RequestDocuments(string stamp) { var documents = this.DocumentsRequestService
public class DocumentsController {
// ctor code is omitted
[HttpPost, Route("api/documents/request/stamp={stamp}")]
public ActionResult RequestDocuments(string stamp) {
var documents = this.DocumentsRequestService.RequestByStamp(stamp);
return new JsonResult(documents);
}
}
DocumentsRequestService
在内部执行以下操作:
using(var requestMessage = new Message()) {
requestMessage.Body = documentStamp;
requestMessage.Recoverable = true;
requestMessage.Label = "request";
requestMessage.ResponseQueue = this.requestedDocumentsResponseQueue;
requestMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
// send request
this.requestedDocumentsQueue.Send(requestMessage);
// synchronously wait for response
var responseMessage = this.requestedDocumentsResponseQueue.Receive();
if(responseMessage.Label.EndsWith("success")) {
return new DocumentsRequestResult(
success: true,
matches: parseMatchesList(responseMessage)
);
}
return new DocumentsRequestResult(
success: false,
matches: Enumerable.Empty<DocumentsRequestMatch>()
);
}
使用(var requestMessage=new Message()){
requestMessage.Body=documentStamp;
requestMessage.Recoverable=true;
requestMessage.Label=“request”;
requestMessage.ResponseQueue=this.requestedDocumentsResponseQueue;
requestMessage.Formatter=newXMLMessageFormatter(新类型[]{typeof(String)});
//发送请求
this.requestedDocumentsQueue.Send(requestMessage);
//同步等待响应
var responseMessage=this.requestedDocumentsResponseQueue.Receive();
if(responseMessage.Label.EndsWith(“成功”)){
返回新文档RequestResult(
成功:没错,
匹配:parseMatchesList(responseMessage)
);
}
返回新文档RequestResult(
成功:错,
匹配项:Enumerable.Empty()
);
}
RequestDocuments
是同步的还是异步的;无论哪种方式,HTTP客户端都会在一段时间后发送请求并接收响应(即异步)
类似地,HTTP web服务器不关心Win32服务是同步实现还是异步实现。它只知道它将一条消息放在一个队列中,一段时间后(即异步)它从队列中获取一条响应消息
据我所知,运行任务使用并行化。而使用async Wait对则会使正在运行的任务异步
有点<代码>任务既可以用于异步代码,也可以用于并行代码,这一事实造成了很多混乱。然而,任务并行库结构,如Parallel
和PLINQ,在并行(非异步)世界中是稳固的
如果多个任务并行运行,可能会有所帮助
我认为“同时”在这里是恰当的术语
首先,请注意,ASP.NET免费提供了大量并发性。如果您想使每个请求在内部并发,那么您可以通过Task.whalll
轻松完成。例如,您可以将DocumentsRequestService
调用更改为异步(假设您的消息队列API支持异步调用):
然后,您可以通过单个控制器操作同时调用它多次,如下所示:
public async Task<ActionResult> RequestDocuments(string stamp1, string stamp2) {
var task1 = this.DocumentsRequestService.RequestByStampAsync(stamp1);
var task2 = this.DocumentsRequestService.RequestByStampAsync(stamp2);
var documents = await Task.WhenAll(task1, task2);
return new JsonResult(documents);
}
公共异步任务请求文档(字符串stamp1、字符串stamp2){
var task1=this.DocumentsRequestService.RequestByStampAsync(stamp1);
var task2=this.DocumentsRequestService.RequestByStampAsync(stamp2);
var documents=wait Task.WhenAll(task1,task2);
返回新的JsonResult(文档);
}
网络调用的“异步”对调用方是透明的。调用方不在乎实现是同步的还是异步的。换句话说,从客户机的角度来看,它总是异步的
例如,HTTP客户机根本不关心RequestDocuments
是同步的还是异步的;无论哪种方式,HTTP客户端都会在一段时间后发送请求并接收响应(即异步)
类似地,HTTP web服务器不关心Win32服务是同步实现还是异步实现。它只知道它将一条消息放在一个队列中,一段时间后(即异步)它从队列中获取一条响应消息
据我所知,运行任务使用并行化。而使用async Wait对则会使正在运行的任务异步
有点<代码>任务既可以用于异步代码,也可以用于并行代码,这一事实造成了很多混乱。然而,任务并行库结构,如Parallel
和PLINQ,在并行(非异步)世界中是稳固的
如果多个任务并行运行,可能会有所帮助
我认为“同时”在这里是恰当的术语
首先,请注意,ASP.NET免费提供了大量并发性。如果您想使每个请求在内部并发,那么您可以通过Task.whalll
轻松完成。例如,您可以将DocumentsRequestService
调用更改为异步(假设您的消息队列API支持异步调用):
然后,您可以通过单个控制器操作同时调用它多次,如下所示:
public async Task<ActionResult> RequestDocuments(string stamp1, string stamp2) {
var task1 = this.DocumentsRequestService.RequestByStampAsync(stamp1);
var task2 = this.DocumentsRequestService.RequestByStampAsync(stamp2);
var documents = await Task.WhenAll(task1, task2);
return new JsonResult(documents);
}
公共异步任务请求文档(字符串