后台工作变量分配在DoWork
本文关键字:DoWork 分配 变量 工作 后台 | 更新日期: 2023-09-27 18:02:29
我使用的BackgroundWorker
与我习惯的有点不同。
通常,我使用BW来更新一些图形控件,并且我在DoWork
方法中执行所有所需的任务,返回结果并对RunWorkerCompleted
事件处理程序进行赋值。
这里,我只是想将一些计算(DB查询)的结果分配给当前窗口的一些私有变量_myList
。
我很惊讶地看到我被允许从DoWork
方法分配列表,我真的很惊讶。
我只是想知道这是正常的,还是因为某些原因不推荐?
你将被允许给变量赋值,因为它没有任何防止跨线程操作的检查,唯一做这些检查的是UI元素。
如果是推荐的话,你就进入了多线程同步的领域。
通常在尝试使用资源之前锁定对资源的访问,以防止诸如竞争条件之类的事情:
static object Locker = new object();
lock (Locker)
{
// variable assignment in here.
}
如果你的用法是基本的,比如,你设置成它,然后在后台工作块的末尾读取它,那么你可以安全地这样做。但是,如果其他东西试图写入它,或者您的代码在对其进行操作之前检查变量内容,那么您将开始获得竞争条件。
我总是尽量避免从后台工作DoWork事件访问任何类型的变量(不仅仅是UI控件)。这似乎在大多数情况下都是有效的,但并不是100%的证据。如果变量是静态的,那么访问它们就没有问题了。
如果我有两个以上的变量工作者需要工作,然后我会倾向于创建一个小的类或结构来保存所有的变量,然后传递给DoWork事件,并返回任何更新的值在后台工作者的e.f result。然后在WorkerCompleted事件中,我可以相应地更新任何本地变量
这是需要的,因为变量不像UI控件那样防止交叉线程。
你必须小心不要让两个不同的线程同时访问对象,特别是如果它是一个更复杂的数据结构,如List或Dictionary,这可能会导致非常奇怪的结果和异常。
如果需要,可以使用lock语句来同步对对象的访问。int、uint等值类型理论上应该没有问题。
MSDN上的这个页面为线程提供了一个很好的起点。
这是完全正常的。只是不允许从创建控件的线程以外的线程访问控件。对于所有其他变量,没有这样的限制。
但是,您需要注意与线程相关的其他问题:如果您有两个线程访问同一个变量,那么如果访问不同步,您可能会遇到问题。
如果你认为在这个过程中用户仍然能够使用UI,那么"离线"同步数据并没有什么错。
我已经做过很多次了。