后台工作者 C# WinForm

6

从后台工作线程加载所有内容是一个不好的想法吗?

当前代码在Form_load事件中执行,我们从Web服务中获取了大量数据。一些长时间运行的工作在后台工作线程中。

无论代码大小如何,从后台工作线程加载所有内容是否是个不好的想法?每个函数都在后台工作线程中运行吗?还是这会使代码变得混乱,成为多线程噩梦?

谢谢。


1
您的标题说是WinForm,但您提到了Page_Load。这是WinForms还是WebForms? - µBio
没有使用足够的不满表达方式。 :P - Russell
7个回答

2
代码的大小并不是您确定是否在单独线程上执行工作的指标,最坏情况下的执行时间才是关键。
首先,很少有UI设计需要在Form_Load中触发大量工作。如果可能的话,我通常会采取以下措施:
- 在响应用户操作之前直接启动该工作。 - 将所有工作移至后台,并异步更新(绑定?)结果到表单。 - 将工作延迟到用户特别执行需要它的某些操作时。
无论正在进行多少工作,您的用户都希望/期望您的表单非常快速和响应。在Form_Load期间执行潜在的长时间运行操作总是会导致糟糕的用户体验。
BackgroundWorker只是执行异步工作的机制之一,还有许多其他机制。您应该为每种情况选择最合适的机制。

这是我们遇到的问题。一些代码在Form_load中调用web_service,但web_service有时会延迟,导致UI无响应,客户认为它已经崩溃了。以前的软件是用PowerBuilder编写的,现在转换成了C#,将每个函数都变成了web_service。他们期望比以前的软件更快,但我们现在要拉取两倍的数据量:'(。谢谢您的回复。 - RedPanda

1

BackgroundWorker 通常用于使 Winforms UI 更加响应。虽然你可以在 Web 应用程序中使用它进行后台处理,但我却不这样做;我在 Windows Service 中使用 ThreadPool


1

将潜在的长时间运行的代码放入后台工人中,以保持应用程序的响应是很好的,但没有必要将所有内容都作为后台工人。

如果您的代码调用Web服务(或任何可能超时的外部系统),或执行某些可能需要较长时间的操作,那么将其放入后台工人是一个不错的选择,但如果任何操作一直需要少于一秒钟的时间才能执行,我可能不会费心去做。


存在协商困难。在这里通常需要多长时间并不重要,重要的是最坏情况下可能需要多长时间。 - hemp

1

后台工作者将花费额外的时间来创建和销毁后台工作者的线程。如果它是一小段代码(在处理方面),则使用主UI线程可能会更快。

如果可维护性是关键,也许使用后台工作者进行处理可能是解决方案。一种自动处理详细信息的自定义框架可能会使代码更易于维护。

这取决于几个因素:

  • 小/大代码片段的数量 - 这将影响同时运行的线程数。
  • 对应用程序的响应能力和性能的重要性
  • 对应用程序可维护性/可扩展性的重要性。

1

这是一个好主意还是不好,很大程度上取决于您的问题的具体情况。您是否必须在一个调用中获取所有数据,还是可以分别获取?

如果是一个长时间运行的 Web 服务调用,那么将其放在线程上对您没有任何帮助。最好的情况是几个独立的、长时间运行的块,需要大约相同的时间返回。

此外,在 WebForms 中(因为您提到了 Page_Load),我IRC 您将与 asp.net 共享线程池,并且在某些并发请求/用户的阈值下,可能会导致您的应用程序整体响应变差。


1
个人而言,除非代码包含特定进程干扰UI响应,否则我不会将代码放入工作线程中。我想不出任何理由把所有东西都放在工作线程上。通常只有在等待外部资源(如Web服务)时才会出现响应问题(除非您正在Form_Load上计算质数 :-)。
如果您还没有探索异步Web服务调用,我建议您看一下。异步调用将为您处理线程 - 这总是一件好事。

谢谢。我会创建一个异步的“Hello World”网络服务。:P - RedPanda

0

从你提到的"Page_Load"来看,似乎你正在一个ASP.NET Web表单中实现这个。如果是这样,并且你想异步调用一个Web服务,那么你应该使用服务的Begin和End invoke函数。如果你需要同时调用多个Web服务而不是顺序调用它们,那么这种方法尤为有效。

享受!


该问题的OP在评论中进行了澄清。我将调整问题以修正错误。 - Russell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接