0

我希望我能在这里得到一些帮助,尝试不同的工作,但总是有一些问题。使用以下示例代码实现的最佳方法是什么:

任务 A + B + C 应该并行运行,但任务 B 应该以任务 A 的一小段延迟开始。根据单个任务 devsearch/conssearch 的结果,他们应该重新启动自己或启动任务“GO”。GO 将只运行一次,并将重新启动调用任务。

如前所述,最好的方法是什么。Parallel.Invoke 这里是合适的选择吗?我应该切换到任务并将其移动到主要部分吗?

我真的很感激任何帮助。提前致谢。请不要在意任务或细节中的小故障,只是将其构建为示例,不要太复杂。

更新/附加信息:

我有一个 Windows 窗体应用程序。逻辑如下:

  1. 我有一个开始按钮,它启动“public async void button1_Click”
  2. 我有 3 个任务

    • “私人异步任务conssearch”
    • “私人异步任务开发搜索”
    • “私人异步任务 GO”

    对于 conssearch 和 devsearch 任务,我给出了谁是发件人、一个布尔值、一个帐户和一个数组的参数。在任务中,我使用 await 执行异步 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);

      }

4

1 回答 1

0

我将只专注于运行这三个任务,没有别的。

首先,开始一个任务,等待一段固定的时间然后开始第二个任务听起来很可疑。延迟的目的是什么?我想不出用这种方式表示最有意义的任何事情。

现在,合并ParallelandTask通常没有多大意义。如果其中一种Parallel方法适合您,请使用它,而不是Tasks。如果您需要更复杂的东西,请使用Tasks。

在您的情况下,由于您可以使用await,我会利用这一点:有一种async方法可以conssearch Task延迟启动 s 。然后,在另一个方法中,调用该方法,启动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);

更好的方法是 convertConsSearchDevSearchto proper async,但很难说这有多难。

于 2013-11-13T16:40:53.723 回答