簡體   English   中英

推遲任務執行

[英]Deferring tasks execution

我正在玩Tasks ,我想推遲執行任務。

我有一個這樣的示例方法:

private async Task<bool> DoSomething(string name, int delayInSeconds)
{
    Debug.WriteLine($"Inside task named: {name}");
    await Task.Delay(TimeSpan.FromSeconds(delayInSeconds));
    Debug.WriteLine($"Finishing task named: {name}");
    return true;
}

我想先創建幾個任務,然后執行一些工作,然后再運行這些任務。 如行Task<bool> myTask = DoSomething("Name", 4); 立即觸發任務,我發現是這樣的:

string[] taskNames = new string[2];

Task<Task<bool>>[] myTasks = new Task<Task<bool>>[2];
myTasks[0] =  new Task<Task<bool>>(async () => await DoSomething(taskNames[0], taskNames[0].Length));
myTasks[1] =  new Task<Task<bool>>(async () => await DoSomething(taskNames[1], taskNames[1].Length));

// I think I can declare it also like this, but this will create tasks later
//IEnumerable<Task<Task<bool>>> myTasks = taskNames.Select(x => new Task<Task<bool>>(async () => await DoSomething(x, x.Length)));

taskNames[0] = "First";
taskNames[1] = "Second";

Debug.WriteLine($"Tasks created");

var results = await Task.WhenAll(myTasks.Select(x => { x.Start(); return x.Unwrap(); }));
Debug.WriteLine($"Finishing: {results.Select(x => x.ToString()).Aggregate((a,b) => a + "," + b) }");

可以不通過包裝方式以其他方式完成此任務嗎?

您可以只使用產生Task委托來簡化一些事情:

string[] taskNames = new string[2];

Func<Task<bool>>[] myTasks = new Func<Task<bool>>[2];
myTasks[0] = new Func<Task<bool>>(async () => await DoSomething(taskNames[0], taskNames[0].Length));
myTasks[1] = new Func<Task<bool>>(() => DoSomething(taskNames[1], taskNames[1].Length)); // Shorter version, near-identical functionally.

// I think I can declare it also like this, but this will create tasks later
//IEnumerable<Task<Task<bool>>> myTasks = taskNames.Select(x => new Task<Task<bool>>(async () => await DoSomething(x, x.Length)));

taskNames[0] = "First";
taskNames[1] = "Second";

Debug.WriteLine($"Tasks created");

var results = await Task.WhenAll(myTasks.Select(x => x()));
Debug.WriteLine($"Finishing: {results.Select(x => x.ToString()).Aggregate((a, b) => a + "," + b) }");

警告 :調用這些委托時, DoSomething將在第一次await同步執行,因此行為類似,但不完全相同

另外,您基於IEnumerable的解決方案也可以正常工作。 只需編寫一個迭代器方法並在啟動它們時yield return任務即可。

就我個人而言,我只是這樣做:

string[] taskNames = new string[2];

taskNames[0] = "First";
taskNames[1] = "Second";

var results = await Task.WhenAll(taskNames.Select(n => DoSomething(n, n.Length)));
Debug.WriteLine($"Finishing: {results.Select(x => x.ToString()).Aggregate((a, b) => a + "," + b) }");   

在您的示例中,您不僅可以“創建Task ”。 您正在調用DoSomething方法,該方法返回 Task 假設這些是async方法,則在編譯器生成的代碼中幕后進行Task創建和啟動。

解決此問題的方法很簡單:在准備好運行方法之前,不要調用該方法。 想象一下,在任何其他情況下,您所要求的行為都會令人困惑。

暫無
暫無

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

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