繁体   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