将异步任务切换到同步任务
本文关键字:同步 任务 任务切换 异步 | 更新日期: 2023-09-27 18:35:54
我有以下代码:
Task.Factory.ContinueWhenAll(items.Select(p =>
{
return CreateItem(p);
}).ToArray(), completedTasks => { Console.WriteLine("completed"); });
是否可以将ContinueWhenAll
转换为同步方法?我想在异步和同步之间切换回来。
编辑:我应该指出,继续时所有方法中的每个"任务"都应该同步执行。
如果要保持现有代码不变,并具有同步执行的变量选项,则应进行以下更改:
bool isAsync = false; // some flag to check for async operation
var batch = Task.Factory.ContinueWhenAll(items.Select(p =>
{
return CreateItem(p);
}).ToArray(), completedTasks => { Console.WriteLine("completed"); });
if (!isAsync)
batch.Wait();
这样,您可以通过编程方式切换它,而不是通过编辑源代码。 您可以保持两种方法的继续代码相同。
编辑:
下面是将相同方法表示为同步和异步版本的简单模式:
public Item CreateItem(string name)
{
return new Item(name);
}
public Task<Item> CreateItemAsync(string name)
{
return Task.Factory.StartNew(() => CreateItem(name));
}
除非我弄错了,否则这就是你要找的
Task.WaitAll(tasks);
//continuation code here
我想你可以试试这个。
对简单方案使用任务延续选项。
var taskFactory = new TaskFactory(TaskScheduler.Defau
var random = new Random();
var tasks = Enumerable.Range(1, 30).Select(p => {
return taskFactory.StartNew(() => {
var timeout = random.Next(5, p * 50);
Thread.Sleep(timeout / 2);
Console.WriteLine(@" 1: ID = " + p);
return p;
}).ContinueWith(t => {
Console.WriteLine(@"* 2: ID = " + t.Result);
}, TaskContinuationOptions.ExecuteSynchronously);
}).ToArray();
Task.WaitAll(tasks);
或将 TPL 数据流用于复杂方案。
var step2 = new ActionBlock<int>(i => {
Thread.Sleep(i);
Console.WriteLine(@"* 2: ID = " + i);
}, new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 1,
//MaxMessagesPerTask = 1
});
var random = new Random();
var tasks = Enumerable.Range(1, 50).Select(p => {
return Task.Factory.StartNew(() => {
var timeout = random.Next(5, p * 50);
Thread.Sleep(timeout / 2);
Console.WriteLine(@" 1: ID = " + p);
return p;
}).ContinueWith(t => {
Thread.Sleep(t.Result);
step2.Post(t.Result);
});
}).ToArray();
await Task.WhenAll(tasks).ContinueWith(t => step2.Complete());
await step2.Completion;