父-子任务-子任务需要花费时间来创建c#(性能问题)

本文关键字:子任务 性能 创建 问题 费时间 | 更新日期: 2023-09-27 18:06:46

我使用以下代码创建父和子任务。父任务的任务只是等待5秒,子任务执行并将结果存储在共享资源中。我已经标记子任务占用时间。

实际上我不知道内部机制,当子线程创建并开始并行执行?

是否有任何文件,我可以知道或是否有其他最好的方式来实现亲子概念?

List<Task> taskList = new List<Task>();
Task parentTask = Task.Factory.StartNew(() =>
{
    int index = 0;
    for (int i = 0; i < 10; i++)
    {
        var task = new Task(() => PrintHello(), TaskCreationOptions.AttachedToParent);
        taskList.Add(task);
        index++;
    }
    foreach (Task task in taskList)
    {
        task.Start();
    }
});
//Wait Parent Task.
parentTask.Wait(5000);
编辑:

应用程序太重(平均每秒5个请求),它应该在5秒内给出响应。

我正在使用task以获得更好的性能。除了任务之外,还有其他方法可以实现并行吗?

父-子任务-子任务需要花费时间来创建c#(性能问题)

从评论来看,似乎每个WCF请求都需要来自10多个外部服务的响应。在这种情况下,最好异步调用每个服务,并等待await Task.WhenAll(tasks);完成所有结果任务,例如:

public async Task CallManyMethods(string someData)
{ 
    var tasks=new []{
        CallSvc1Async(someData),
        CallSvc2Async(someData),
    }
    var results=await Task.WhenAll(tasks);
    ...
    //Unpack the results and keep processing them
}
public async Task<string> CallSvc1Async(string someData)
{
    var response=await _svc1Proxy.GetStuffAsync(someData);
    //build a result from the response
    return result;
}
public async Task<string> CallSvc2Async(string someData)
{
    var url=....
    var json=await _httpClient.GetStringAsync(url);
    ....
    return result;
}

所有方法返回字符串仅用于演示目的。

每个方法将发送调用到外部服务,然后释放其线程,直到收到响应。这样,线程在等待响应时不会被阻塞,并且总等待时间仅由最慢的外部服务决定。

CallManyMethods也不阻塞。当await Task.WhenAll被执行时,执行线程将被释放。一旦所有调用完成,执行将在await行之后恢复。

结果是不需要创建父任务和子任务,因为TPL已经可以处理这个场景。开销很小,因为没有线程阻塞等待外部服务完成。

这意味着少量的线程可以处理大量的请求。

我引用@PanagiotisKanavos——没有理由让启动任务触发其他任务。您可能会遇到线程池耗尽的问题—一次只能创建这么多线程—之后您将不得不等待创建新线程;你也没有检查任务是否会完成(从可靠性的角度来看,这不是很好)

parentTask.Wait(5000);

将等待5秒并继续- parentTask不会被杀死-它返回一个布尔值告诉您任务是否及时完成,但如果任务触发了新线程,则线程仍将运行。

如何强制低延迟&web服务执行一些冗长操作的可靠性:

  1. 将传入的请求持久化到持久存储(db, cloud等)
  2. 创建批处理应用程序(窗口服务),它将从队列中获取记录并执行它们

如果你的客户需要这个冗长操作的结果,你只有一个选择-扩大规模(web farm/cloud)。

还需要注意的是,更多的线程并不等于更好的性能——线程对于等待IO操作或者在有问题的机器上有多个内核是很好的,但是如果没有IO操作并且只有一个内核,你实际上会使你的代码变慢。

我建议你参考下面的组件,可能会解决你的问题。

章鱼。TaskTree

您可以灵活地在父任务上设置await,以串行或并发的方式启动子任务。

请参考给出的代码片段,它可以使您清楚地了解组件的用途。