【问题标题】:Multiple Background workers in web forms applicationWeb 表单应用程序中的多个后台工作人员
【发布时间】:2017-08-25 16:35:00
【问题描述】:

我有一个需求,客户端向单个网页发出请求,该网页需要从其他两个网页检索结果。

我们请求信息的两个网页在返回结果之前执行一个过程,这个过程可能需要几分钟,所以与其启动一个网络请求并等待它返回然后再启动另一个我想触发关闭后台工作人员中的两个请求并并行生成结果。

所以我的代码看起来像这样(伪代码):

var worker1 = new BackgroundWorker();
var worker2 = new BackgroundWorker();

worker1.DoWork += (s, e) => {
//Web Request done here
};

worker2.DoWork += (s, e) => {
    //Web Request done here
};

worker1.RunWorkerAsync();
worker2.RunWorkerAsync();

//Some logic here that basically waits for both to return.

现在我注意到返回结果的时间仍然比我预期的要长,所以我做了一些测试并将 Dowork 的内容更改为

using (var sw = new StreamWriter(@"c:\temp\TEST\Worker1.txt")) 
{
    for (int i = 0; i < 1000000; i++)
    {
        sw.WriteLine($"{i} - {DateTime.Now.ToLongTimeString()}");
    }
}

为简洁起见,我不会将其复制回来,但假设文件名在第二个工人 DoWork() 中更改为 worker2.txt

我知道它很粗糙,但它有效,写出 100 万次时间大约需要 3 秒,所以在第一个文件中,我看到的时间范围从 Execution Time 到 Execution Time + 3 seconds 在第二个文件中,我可以看到从执行时间 + 3 秒到执行时间 + 6 秒的时间。

所以现在很明显,一个工人先被执行,然后另一个工人被执行,但我不明白为什么。

有关该项目的更多信息 - Web 表单(这是我得到的并且必须坚持的要求).net 4.5

**编辑添加:**

回到这个问题后,我查看了我正在调用的页面,并注意到它们在页面声明中有 aspcompat=true,我认为这是导致问题的原因(他们需要这个,我不能删除它)。

我现在有什么选择?理想情况下,我希望能够调用这些页面以并行运行,有没有办法在将 aspcompat 设置为 true 的情况下仍然实现这一点?


为未来的读者编辑

请注意,我上面描述的问题和提供的代码是正确的,我遇到的问题是我调用的页面被设置为使用 ASPCOMPAT,这会强制 webforms 在 STA 模式下工作,这就是把我甩了。

最后上面的代码没有改变,解决方案是将带有后台工作人员的页面放在一个单独的 Web 应用程序中,该应用程序有自己的应用程序池,该页面 n 使用后台工作人员来调用正在运行的页面在他们的应用程序池中处于 aspcompat 模式 - 这并不理想,但无论如何我们想要实时部署。

【问题讨论】:

  • 为什么不直接使用 async/await?避免所有 BackgroundWorker 废话,然后是 Task.WaitAll()
  • 与上述行为相同。

标签: c# webforms backgroundworker


【解决方案1】:

您可以跳过BackgroundWorker 而使用Task.WaitAll()

void Main()
{
    Task.WaitAll(FirstRequest(), SecondRequest());
}

// Define other methods and classes here
private async static Task FirstRequest()
{
    // Do your work for one of the WebRequests here
    await Task.Delay(3000);
    Console.WriteLine("Done with 1");
}

private async static Task SecondRequest()
{
    // Do your work for the second WebRequest here
    await Task.Delay(3000);
    Console.WriteLine("Done with 2");
}

【讨论】:

  • 我的第一个想法是使用异步方法并等待它,但这会得到相同的行为。用我刚刚在我正在调用的页面中发现的内容更新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多