父子任务-子任务需要时间来创建C#(性能问题)
我使用以下代码创建父任务和子任务。父任务的作业只需等待5秒,子任务执行并将结果存储在共享资源中。 我已经标记出子任务需要时间 实际上我不知道当创建子线程并开始并行执行时的内部机制 是否有我可以知道的任何文档,或者是否有其他最好的方法来实现父子概念父子任务-子任务需要时间来创建C#(性能问题),c#,multithreading,task,C#,Multithreading,Task,我使用以下代码创建父任务和子任务。父任务的作业只需等待5秒,子任务执行并将结果存储在共享资源中。 我已经标记出子任务需要时间 实际上我不知道当创建子线程并开始并行执行时的内部机制 是否有我可以知道的任何文档,或者是否有其他最好的方法来实现父子概念 List<Task> taskList = new List<Task>(); Task parentTask = Task.Factory.StartNew(() => { int index = 0;
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);
List taskList=new List();
Task parentTask=Task.Factory.StartNew(()=>
{
int指数=0;
对于(int i=0;i<10;i++)
{
var task=新任务(()=>PrintHello(),TaskCreationOptions.AttachedToParent);
任务列表。添加(任务);
索引++;
}
foreach(任务列表中的任务)
{
task.Start();
}
});
//等待父任务。
parentTask.Wait(5000);
编辑:
应用程序太重(平均每秒5个请求),应在5秒内给出响应
我使用任务来提高性能。
除了task之外,还有其他方法来实现并行性吗?我将引用@PanagiotisKanavos-没有理由让startup task触发其余任务。您可能遇到了线程池不足的问题—一次只能创建这么多线程—之后您必须等待创建新线程;此外,您没有检查任务是否会完成(从可靠性的角度来看,这不是很好) 只需等待5秒并继续-不会终止
parentTask
-它返回一个布尔值,告诉您任务是否及时完成,但如果任务触发了新线程,线程仍将运行
如何强制Web服务执行一些长时间操作的低延迟和可靠性:
还要注意的是,更多的线程并不意味着更好的性能-线程对于等待IO操作或者如果您有多个内核在讨论中,那么线程是非常好的,但是如果没有IO操作,只有一个内核,那么实际上您正在使代码变慢。从注释中可以看出,似乎每个WCF请求都需要来自10多个外部服务的响应。在这种情况下,最好异步调用每个服务,并使用
wait 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(字符串someData)
{
var tasks=new[]{
CallSvc1Async(某些数据),
CallSvc2Async(someData),
}
var结果=等待任务.WhenAll(任务);
...
//将结果解压缩并继续处理
}
公共异步任务调用Svc1Async(字符串someData)
{
var response=await_svc1Proxy.GetStuffAsync(someData);
//根据响应生成结果
返回结果;
}
公共异步任务CallSvc2Async(字符串someData)
{
变量url=。。。。
var json=await\u httpClient.GetStringAsync(url);
....
返回结果;
}
所有方法返回的字符串仅用于演示目的
每个方法将向外部服务发送调用,然后释放其线程,直到收到响应。这样,线程就不会被阻塞等待响应,总等待时间只由最慢的外部服务决定
CallManyMethods
也不会阻止。执行线程将在等待任务时释放。所有执行时释放。一旦所有调用完成,执行将在wait
行之后恢复
结果是不需要创建父任务和子任务,因为TPL已经可以处理这个场景了。开销最小,因为没有线程块等待外部服务完成
这意味着少量线程可以处理数量多得多的请求。任务不是线程。您不必在这里创建新线程。线程没有父线程。任务可以有父母。你想解决的实际问题是什么?为什么要在任务之间建立父子关系?你为什么创造冷任务?几乎可以肯定,有更好的方法来解决实际问题。例如,使用Parallel.Invoke
或使用Task.whalll
等待一个活动数组的完成tasks@Gusdor-你说得对。我的意思是儿童任务需要时间。线程和任务与我发现的不同。请查看System.ComponentModel。BackgroundWorker@AdamFinleyBackgroundWorker已经过时,只适用于WinForms应用程序。它不能在不同的任务之间创建任何类型的关系,执行连续性等。它本质上与调用任务相同。运行并使用进度对象来报告事件,只需要组件开销,无法组合多个操作。Application server有8个核心和16 GB RAM。是的,所有10到12个任务都没有IO操作,但我希望所有任务都应该并行、快速运行,并在4到5秒内返回每个任务的结果。还有其他并行方式吗?如果他执行的是IO广泛而不是CPU密集型的操作,异步IO肯定是一种方式。@Panagiotis Kanavos-谢谢你的回答!你们是对的,我可以使用这个方法,但我认为,当所有异步方法都执行时,Task.whalll(任务)就会执行。若异步方法花费的时间超过5秒,那个么我不想等待asyn方法,而想继续使用主线程。
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;
}