【问题标题】:Background worker variable assignments in DoWorkDoWork 中的后台工作人员变量分配
【发布时间】:2011-07-18 18:45:42
【问题描述】:
我使用的 BackgroundWorker 与我以前使用的有点不同。
通常,我使用 BW 更新一些图形控件,并在 DoWork 方法中执行所有必需的任务,返回结果并分配给 RunWorkerCompleted 事件处理程序。
在这里,我只是想将一些计算(数据库查询)的结果分配给当前窗口的一些私有变量_myList。
看到DoWork 方法允许我分配列表,我感到非常惊讶,我真的很惊讶。
我只是想知道这是正常的还是由于某种原因不推荐?
【问题讨论】:
标签:
c#
wpf
backgroundworker
【解决方案1】:
您将被允许分配给该变量,因为它没有任何防止跨线程操作的检查,唯一进行这些检查的是 UI 元素。
至于是否推荐,你正在步入多线程同步的领域。
通常您在尝试使用资源之前锁定对资源的访问,以防止出现竞争条件等情况:
static object Locker = new object();
lock (Locker)
{
// variable assignment in here.
}
如果您的使用是基本的,例如,您将其设置在其中,然后在您从中读取的后台工作程序块的末尾,那么您将可以安全地执行此操作。但是,如果其他东西试图写入它,或者您有代码在对其进行操作之前检查变量内容,那么您就会开始获得竞争条件。
【解决方案2】:
我总是尽量避免从后台工作人员 DoWork 事件中访问任何类型的变量(不仅仅是 UI 控件)。它似乎在大多数情况下都有效,但并不是 100% 的证明。如果变量是静态的,那么我在访问它们时没有问题。
如果我有多个变量需要工作人员使用,那么我倾向于创建一个小类或结构来保存所有变量,然后将其传递给 DoWork 事件并在 e.Result 中返回任何更新的值后台工作人员。然后在 WorkerCompleted 事件中,我可以相应地更新任何局部变量
【解决方案3】:
这是需要的,因为变量不像 UI 控件那样不受跨线程保护。
你必须小心不要让两个单独的线程同时访问对象,特别是如果它是一个更复杂的数据结构,如 List 或 Dictionary,这可能会导致非常奇怪的结果和异常。
若需要同步访问对象,您可以使用lock 语句(如果需要)。
int、uint等值类型理论上应该没问题。
MSDN 上的This 页面为线程提供了一个很好的起点。
【解决方案4】:
这是完全正常的。您只是不允许从与创建它们的线程不同的线程访问控件。对于所有其他变量,没有这样的限制。
但是,您需要注意与线程相关的其他问题:如果您有两个线程访问同一个变量,如果访问不同步,您可能会遇到问题。
【解决方案5】:
如果您认为在此过程发生时用户仍然能够使用 UI 是合理的,那么可以说“离线”同步数据没有任何问题。
我已经做了很多。尤其是在开发移动应用程序时。