锁定WinForms控件

4

我需要确保一旦执行进入一个方法,该方法接收到的控制权不会被另一个线程改变。基本上,我的想法是这样的:

private void doSomeWork(Control control) {
    lock (control) {
        // do some stuff with the control...
    }
}

这是一个不好的主意吗?

编辑:

实际上,我想做的是确保在我执行控件的某些方法(顺便说一下,这些方法将通过反射执行)时,该控件不会被另一个线程销毁。

4个回答

3
在良好的应用程序中,Windows表单控件已经被限制为仅能在一个线程中访问。如果任何线程试图访问在另一个线程中创建的控件,则会抛出异常。
你的代码没有问题,只是现在它在大多数情况下是无用的,除非你正在通过保护进行黑客攻击(这是可能的)。
通常,在工作线程中创建或操作数据时,工作线程将向UI线程发送事件以更新UI。绝不应该由工作线程自己更新UI,否则会自动失败。

0

虽然我没有很多线程编程的经验,但是我建议你使用匿名委托在一个新线程中启动表单控件:

t= new Thread(delegate() {
    MyMethodToInvokeTheWinFormControl();
   });

t.Start();

0

其实 Fernando,这不是一个坏主意,但这不是正确的锁定方式。你需要仔细阅读 .Net 中锁定语句的作用:

http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx

我认为根据您的陈述,您期望整个对象被锁定,或以某种方式使其对线程安全,因为对象本身在已锁定的代码块中使用。实际发生的是该代码块被锁定并且不允许两个或更多线程同时执行。如果该代码块是您将要操作控件的唯一位置,则可以使用,否则您需要在对象本身上进行同步锁定。

0

这完全取决于你所说的“未更改”的含义。

如果你的意思是“任何其他线程都不能以任何方式完全更改此控件”,那么锁定并不是这样工作的。

在这种情况下,锁定不像房门上的常规锁那样。它更像是一个小黄色便签,上面写着“已锁定”。只要其他线程读取便签并遵守其内容,就应该没问题,但是任何不关心便签的其他线程当然可以随意操纵您的控件。

无论如何,你到底想要实现什么?你永远不应该从除主线程以外的线程中操作控件,因此问题本来就不应该存在。

相反,你应该通过在控件上使用Invoke方法将所有工作调度到主线程上。


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