簡體   English   中英

切換異步任務以同步任務

[英]Switch async Task to sync task

我有以下代碼:

Task.Factory.ContinueWhenAll(items.Select(p =>
{
    return CreateItem(p);
}).ToArray(), completedTasks => { Console.WriteLine("completed"); });

是否可以將ContinueWhenAll轉換為同步方法? 我想在異步和同步之間切換。

編輯:我應該提到continuewhenall方法中的每個“任務”都應同步執行。

除非弄錯了,否則這就是您要尋找的

Task.WaitAll(tasks);
//continuation code here

如果您希望保持現有代碼不變,並具有同步執行的可變選項,則應進行以下更改:

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));
}

我想你可以試試看。

在一個簡單的場景中使用TaskContinuationOptions

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 Dataflow

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM