簡體   English   中英

C# 命名任務的正確方法是什么?

[英]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 ,它的工作原理如下:

來自MSDN 的關於取消Task的頁面

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.

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