简体   繁体   English

针对此特定星座使用TPL的正确方法(连续并行任务)

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

i hope i can get some help here, tried different things that work, but always with some problems. 我希望我能在这里得到一些帮助,尝试了各种可行的方法,但始终会遇到一些问题。 What would be the best way to achieve with the sample code the following: 使用以下示例代码将是最好的方法:

Task A + B + C should run parallel, but Task B should start with a small delay to task A. Depending on the result of the single Tasks devsearch/conssearch, they should just restart themselves or start task "GO". 任务A + B + C应该并行运行,但是任务B应该比任务A稍有延迟地开始。根据单个任务devsearch / conssearch的结果,它们应该自行重启或启动任务“ GO”。 GO will run only once and will restart the calling task. GO将仅运行一次,并将重新启动调用任务。

As already said, what would be the best way to do this. 如前所述,什么是最好的方法。 Is Parallel.Invoke here the suitable option? Parallel.Invoke在这里合适吗? Should i switch to Tasks and move it to the Main Section? 我应该切换到“任务”并将其移到“主要部分”吗?

I really appreciate any help. 我非常感谢您的帮助。 Thanks in Advance. 提前致谢。 Please do not care about small faults in the tasks or the details, just built this as example to do not have it too complex. 请不要在意任务或细节中的小错误,仅以构建此示例为例,不要太复杂。

UPDATE/Additional Information: 更新/其他信息:

I have a Windows Form Application. 我有一个Windows窗体应用程序。 The logic is the following: 逻辑如下:

  1. I have a start button, which starts "public async void button1_Click" 我有一个开始按钮,它会启动“公共异步无效按钮1_Click”
  2. I have 3 Tasks 我有3个任务

    • "private async Task conssearch" “私有异步任务conssearch”
    • "private async Task devsearch" “私有异步任务devsearch”
    • "private async Task GO" “私有异步任务GO”

    For the tasks conssearch and devsearch i give the parameters who is the sender, a bool, an Account and an Array. 对于conssearch和devsearch的任务,我给出了谁是发送者,布尔,帐户和数组的参数。 In the tasks i perform asynch http requests with await. 在任务中,我执行等待的异步HTTP请求。 This request is done for each item in the Array. 对数组中的每个项目都完成了此请求。 For the http requests i need logindata, this is passed via the Account. 对于http请求,我需要登录数据,这是通过帐户传递的。 I can login multiple times ( Cookiehandling etc. is done and working ), that is why i want to run conssearch parallel at the same time. 我可以多次登录(Cookiehandling等已完成并正在工作),这就是为什么我想同时并行运行conssearch的原因。 The delay between the parallel execution of conssearch is needed, bcause i don´t want to have the same results. 需要并行执行conssearch之间的延迟,因为我不想获得相同的结果。 I have a rps limit per account, that is why i have await.delay within the single tasks. 我每个帐户都有一个rps限制,这就是为什么我在单个任务中都有await.delay的原因。

    So in summary i want to start parallel conssearch x 2 and devsearch when i press the Start Button. 因此,总之,我想在按下“开始”按钮时启动并行conssearch x 2和devsearch。

  3. Now Every single task should run independant from each other. 现在,每个任务都应彼此独立运行。

    • If i get in the Tasks conssearch and devsearch the result i am expecting, i will start "private async Task GO" and pass the same parameters. 如果我进入Tasks conssearch和devsearch我期望的结果,我将启动“ private async Task GO”并传递相同的参数。 This is done bcause i want that "private async Task GO" starts the calling Task again after it is finished. 这样做是因为我希望“专用异步任务GO”在完成后再次启动调用任务。
    • If i do not get the expected result, the Task should restart 如果我没有得到预期的结果,任务应该重新启动

I hope it is now a bit better understandable what i am trying to do. 我希望现在可以更好地理解我要做什么。

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);

      }

I'm going to focus only on running the three tasks, nothing else. 我将只专注于运行这三个任务,仅此而已。

First of all, starting one task, waiting a constant amount of time and then starting a second task sounds suspicious. 首先,开始一个任务,等待固定的时间,然后开始第二个任务,这听起来很可疑。 What is the purpose of the delay? 延迟的目的是什么? I can't think of anything that would make the most sense to represent this way. 我想不出最能代表这种方式的东西。

Now, combining Parallel and Task usually doesn't make much sense. 现在,将ParallelTask结合起来通常没有多大意义。 If one of the Parallel methods works for you, use that, not Task s. 如果Parallel方法之一适合您,请使用该方法,而不要使用Task If you need something more complicated, use Task s. 如果您需要更复杂的东西,请使用Task

In your case, since you can use await , I would take advantage of that: have one async method that starts the conssearch Task s with the delay. 在您的情况下,由于可以使用await ,因此我将利用这一优势:有一个async方法可以延迟启动conssearch Task Then, in another method, call that method, start the devsearch Task and wait for both to complete. 然后,在另一个方法中,调用该方法,启动devsearch Task然后等待两者均完成。 Something like: 就像是:

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);

Even better approach would be to convert ConsSearch and DevSearch to proper async , but it's difficult to tell how hard would that be. 更好的方法是将ConsSearchDevSearch转换为适当的async ,但是很难说这将有多困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM