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