在DoWork中的后台工作变量赋值

3

我正在使用BackgroundWorker,但是我使用的方式与以往不同。

通常,我使用BW来更新一些图形控件,并在DoWork方法中执行所有必需的任务,返回结果并对RunWorkerCompleted事件处理程序执行赋值操作。

这里,我只想将某些计算(DB查询)的结果分配给当前窗口的某个私有变量_myList

我非常惊讶地发现,我可以从DoWork方法中分配列表,并且我真的很惊讶。

我只是想知道这是否正常,或者出于某种原因不建议这样做?

5个回答

4

由于变量没有任何防止跨线程操作的检查,因此您将被允许对其进行分配,唯一执行这些检查的是UI元素。

至于是否建议这样做,您正在涉足多线程同步领域。

通常,在尝试使用资源之前锁定对其的访问,以防止诸如竞态条件之类的问题:

static object Locker = new object();

lock (Locker)
{
   // variable assignment in here.
}

如果您的使用是基本的,例如,您将其设置为后台工作器块,然后在其末尾读取,则可以安全地这样做。但是,如果其他内容试图向其写入,或者您有检查变量内容以便采取行动的代码,则开始出现竞争条件。

3
我会尽量避免在后台工作程序的DoWork事件中访问任何类型的变量(不仅限于UI控件)。虽然它似乎大部分时间都能正常工作,但并非百分之百可靠。如果变量是静态的,则我不会访问它们而感到困扰。
如果我有多个变量需要后台工作程序处理,那么我会倾向于创建一个小的类或结构来保存所有变量,然后将其传递给DoWork事件,并在后台工作程序的e.Result中返回任何更新的值。然后在WorkerCompleted事件中,我可以相应地更新任何本地变量。

2

这是需要的,因为变量不像UI控件一样受到跨线程的保护。

你必须小心,不要让两个单独的线程同时访问对象,特别是如果它是一个更复杂的数据结构,比如List或Dictionary,这可能会导致非常奇怪的结果和异常。

如果需要同步访问对象,可以使用lock语句。

理论上,值类型如int、uint等应该没有问题。

这个MSDN页面提供了一个很好的线程起点。


1

这是完全正常和可以的。您只是不允许从创建它们的不同线程访问控件。对于所有其他变量,没有这样的限制。
但是,您需要小心与线程相关的其他问题:如果有两个线程访问同一个变量,如果访问未同步,可能会遇到问题。


0

如果您认为在此过程发生时用户仍然能够使用UI是合理的,那么“离线”同步数据并没有任何问题。

我经常这样做,特别是在开发移动应用程序时。


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