[英]C# Named Tasks What's the proper way?
我正在嘗試處理串聯任務。
我的想法是有一些類似於下一個代碼的東西,但 VS 將我的代碼標記為:
無法在 Argument1 中從“System.Threading.Tasks.Task”轉換為“System.Action”
什么是正確的語法?
public void startAllTasks()
{
Task task1 = new Task(() => GetLocalDbRecords());
Task task2 = new Task(() => CreatePlainTextFile());
Task task3 = new Task(() => SendToWS());
task1.ContinueWith(task2);
task2.ContinueWith(task3);
task1.Start();
}
我通過使用下一個代碼得到了我想要的結果(我知道我必須優化它),但我的想法是通過使用“ContinueWith”和一個 CancellationToken 來改進它,但還沒有運氣
public void startAllTasks()
{
records = 0;
stopFlag = false;
tasksRunning = new Dictionary<int, bool>();
tasksRunning.Add(1, false);
tasksRunning.Add(2, false);
tasksRunning.Add(3, false);
currentStep = 0;
while (!stopFlag)
{
if (currentStep == 0 && !tasksRunning[1])
{
tasksRunning[1] = true;
Task task1 = new Task(() => this.GetLocalDbRecords());
task1.Start();
}
if (currentStep == 1 && !tasksRunning[2])
{
tasksRunning[2] = true;
Task task2 = new Task(() => this.CreatePlainTextFile());
task2.Start();
}
if (currentStep == 3 && !tasksRunning[3])
{
tasksRunning[3] = true;
Task task3 = new Task(() => this.SendToWS());
task3.Start();
}
Thread.Sleep(100);
}
}
這是正確的語法(下面的解釋):
Task task1 = new Task(() => GetLocalDbRecords());
Task task2 = new Task(() => CreatePlainTextFile());
Task task3 = new Task(() => SendToWS());
task1.ContinueWith(x => task2.Start());
task2.ContinueWith(x => task3.Start());
task1.Start();
請注意, ContinueWith
方法不會接收一個Task
它接收一個Action<Task>
,這個Action
在第一個Task
完成后被調用,它將接收第一個Task
作為參數,因此您可以使用它的返回值。
您還可以使用Task.Factory
這種流暢語法,這也消除了您使用Task.Start()
:
Task.Factory.StartNew(GetLocalDbRecords)
.ContinueWith(x => CreatePlainTextFile())
.ContinueWith(x => SendToWS())
.Wait();
為了使用CancellationToken
您需要使用CancellationTokenSource
,它的工作原理如下:
1) 創建並啟動一個可取消的任務。
2) 將取消令牌傳遞給您的用戶委托,並可選擇傳遞給任務實例。
3) 在您的用戶委托中通知並響應取消請求。
4) 可選地在調用線程上通知任務被取消。
和一個代碼示例:
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
Task.Factory.StartNew(GetLocalDbRecords)
.ContinueWith(x => CreatePlainTextFile(), tokenSource.Token)
.ContinueWith(x => SendToWS(), tokenSource.Token);
tokenSource.Cancel();
bool cancelationRequested = token.IsCancellationRequested; //Value will be true.
使用tokenSource.Cancel();
時, Task
不會自動停止tokenSource.Cancel();
因為它們可能在調用它們的同一個Thread
上運行,並且它們必須知道CancellationToken
並輪詢IsCancellationRequested
如果他們希望根據它停止,但是,如果Task
或其連續Task
試圖在CancellationToken
已經被請求取消時,首先不會調用Task
或其連續的Task
。
此外,您可以使用CancellationTokenSource.CancelAfter(TimeSpan)
在取消之前設置超時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.