簡體   English   中英

針對此特定星座使用TPL的正確方法(連續並行任務)

[英]Right way of using TPL for this specific constellation ( Continuous parallel Tasks )

我希望我能在這里得到一些幫助,嘗試了各種可行的方法,但始終會遇到一些問題。 使用以下示例代碼將是最好的方法:

任務A + B + C應該並行運行,但是任務B應該比任務A稍有延遲地開始。根據單個任務devsearch / conssearch的結果,它們應該自行重啟或啟動任務“ GO”。 GO將僅運行一次,並將重新啟動調用任務。

如前所述,什么是最好的方法。 Parallel.Invoke在這里合適嗎? 我應該切換到“任務”並將其移到“主要部分”嗎?

我非常感謝您的幫助。 提前致謝。 請不要在意任務或細節中的小錯誤,僅以構建此示例為例,不要太復雜。

更新/其他信息:

我有一個Windows窗體應用程序。 邏輯如下:

  1. 我有一個開始按鈕,它會啟動“公共異步無效按鈕1_Click”
  2. 我有3個任務

    • “私有異步任務conssearch”
    • “私有異步任務devsearch”
    • “私有異步任務GO”

    對於conssearch和devsearch的任務,我給出了誰是發送者,布爾,帳戶和數組的參數。 在任務中,我執行等待的異步HTTP請求。 對數組中的每個項目都完成了此請求。 對於http請求,我需要登錄數據,這是通過帳戶傳遞的。 我可以多次登錄(Cookiehandling等已完成並正在工作),這就是為什么我想同時並行運行conssearch的原因。 需要並行執行conssearch之間的延遲,因為我不想獲得相同的結果。 我每個帳戶都有一個rps限制,這就是為什么我在單個任務中都有await.delay的原因。

    因此,總之,我想在按下“開始”按鈕時啟動並行conssearch x 2和devsearch。

  3. 現在,每個任務都應彼此獨立運行。

    • 如果我進入Tasks conssearch和devsearch我期望的結果,我將啟動“ private async Task GO”並傳遞相同的參數。 這樣做是因為我希望“專用異步任務GO”在完成后再次啟動調用任務。
    • 如果我沒有得到預期的結果,任務應該重新啟動

我希望現在可以更好地理解我要做什么。

public async void button1_Click(object sender, EventArgs e)
    {

            while (true)
            {

                Parallel.Invoke(
                   () => {
                        Task taskA = Task.Factory.StartNew(() => conssearch("cons", false, Account1, devArr));
                        System.Threading.Thread.Sleep(335);
                        Task taskB = Task.Factory.StartNew(() => conssearch("cons", false, Account2, devArr));

                        taskA.Wait();
                        taskB.Wait();
                    },

                    () => Task.Run(() => devsearch("dev", false, Account3, devArr)),

                    );

        }

    }



    private async Task conssearch(object sender, bool GO, string acc, Array[] devArr)
    {

                for (int i = 0; i < devArr.Length; i++)
                {

                    // Do some HTTP here....

           If ....
           GO = True;
                }
               await Task.Delay(100);

                    if (GO)
                    {
                        listView1.BeginInvoke(new MethodInvoker(() => listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)));
                        listView2.BeginInvoke(new MethodInvoker(() => listView2.Items.Clear()));                      
                        GO("cons", acc, devArr);
                    }
                        else
                        {
                        //conssearch("cons", false, acc, devArr)
                        }
        }




    private async Task devsearch(object sender, bool GO, string acc, Array[] devArr)
    {

                 for (int i = 0; i < devArr.Length; i++)
                 {

                    // Do some HTTP here....

                        If ....
                        GO = True;
               }
               await Task.Delay(100);

                if (GO)
                {
                    listView1.BeginInvoke(new MethodInvoker(() => listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)));
                    listView2.BeginInvoke(new MethodInvoker(() => listView2.Items.Clear()));
                    GO("cons", acc, devArr);
                }
                    else
                    {
                    //devsearch("dev", false, acc, devArr)
                    }
    }


    private async Task GO(object sender, string acc, Array[] devArr)
      {

{
                          // Do some HTTP here....
            }
           await Task.Delay(100); 

              if (sender == "tra")
                await conssearch(sender, false, client, devArr);
              else  
                await devsearch(sender, false, client, devArr);

      }

我將只專注於運行這三個任務,僅此而已。

首先,開始一個任務,等待固定的時間,然后開始第二個任務,這聽起來很可疑。 延遲的目的是什么? 我想不出最能代表這種方式的東西。

現在,將ParallelTask結合起來通常沒有多大意義。 如果Parallel方法之一適合您,請使用該方法,而不要使用Task 如果您需要更復雜的東西,請使用Task

在您的情況下,由於可以使用await ,因此我將利用這一優勢:有一個async方法可以延遲啟動conssearch Task 然后,在另一個方法中,調用該方法,啟動devsearch Task然后等待兩者均完成。 就像是:

async Task RunConsSearches()
{
    var taskA = Task.Run(() => ConsSearch("cons", false, Account1, devArr));
    await Task.Delay(335);
    var taskB = Task.Run(() => ConsSearch("cons", false, Account2, devArr));

    await Task.WhenAll(taskA, taskB);
}

…

var consSeachTask = RunConsSearches();
var devSearchTask = Task.Run(() => DevSearch("dev", false, Account3, devArr));
await Task.WhenAll(consSeachTask, devSearchTask);

更好的方法是將ConsSearchDevSearch轉換為適當的async ,但是很難說這將有多困難。

暫無
暫無

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

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