【发布时间】:2026-01-29 20:40:01
【问题描述】:
我刚刚开始处理任务。我们有一个使用请求/响应的系统设置。运行任务的服务接受具有请求对象列表的主请求并返回具有响应对象列表的主响应。所以它看起来像这样
var MasterRequest = new MasterRequest;
MasterRequest.Requests.Add(new BlueRequest);
MasterRequest.Requests.Add(new RedRequest);
MasterRequest.Requests.Add(new YellowRequest);
请求实现了一个简单的 IRequest 接口,每种颜色都是一个具体的类。该服务具有设置为能够根据具体请求对象分别和同时处理每个请求的具体类(请求处理器)。服务上的每个具体类都有一个 GetTask 方法,其签名如下:
Task<IResponse> GetTask(IRequest);
{
// some setup stuff
return Task.Factory.StartNew<IResponse>(() =>
{
// do task stuff
return response; // implements IResponse
});
}
我的服务接受传入的 MasterRequest 并通过在具体请求处理器上调用上面列出的 GetTask 调用来构建任务列表。然后我使用列表中的 Parallel.ForEach 来处理任务。
// this is what is returned from the service.
// it has a List<IResponse> on it to hold the resposnes
MasterResposne resposne = new MasterResponse();
List<Task<IResponse>> tasks = new List<Task<IResponse>>();
foreach(IRequest req in MasterRequest.Requests)
{
// factory to get the proper request processor
RequestProcessor p = rp.GetProcessor(req);
tasks.add(p.GetTask(req));
}
Parallel.ForEach(tasks, t =>
{
t.Wait();
// check for faulted and cancelled
// this is where I need help
response.Responses.Add(t.Result);
}
这一切都很好。但是,如果任务引发异常,我不知道如何将其与触发它的特定具体请求联系起来。我需要知道,这样我才能将正确构建的响应传回给调用者。
我的第一个想法是对 Task 进行子类化,但这带来了我不想处理的一系列问题。
我读了这篇 SO 文章,似乎我想做这样的事情
Is this ok to derive from TPL Task to return more details from method?
我认为 Reed 的第二个示例是我的解决方案,但我仍然看不到如何同时运行任务并能够将异常与请求联系起来,以便我可以返回正确构建的响应列表。
提前致谢。
【问题讨论】:
-
1) 我认为启动任务的推荐方法是 Task.Run() 2) 您可以深入研究 TaskCompletionSource。这里有一些对我有很大帮助的链接:msdn.microsoft.com/en-us/magazine/jj991977.aspxdocs.microsoft.com/en-us/dotnet/standard/…scalablenotions.wordpress.com/2015/05/02/…
-
也许 Task.WaitAll() 会比 Parallel 更好?
-
@Fildor 这是一个很好的链接。我还有一些其他要求迫使我拥有自定义任务调度程序,因此我不得不使用 Task.Factory.StarNew 调用。
标签: c# .net asynchronous task task-parallel-library