Electronic Joint Business

Solution for E-Business

细谈UI线程的SynchronizationContexts

[b]为什么需要SynchronizationContexts[/b] 在图中的演示里,我试图用ironruby或者ironpython去控制一只小乌龟,(就是那个三角箭头),通过ironruby的命令让小乌龟前进、后退、左转、右转。 这里存在一个线程同步的问题,敲下一个命令之后,屏幕上的UI物件应该要马上按指令运作(体会一下魔兽世界的宏),所以小乌龟工作在一个UI线程里,而命令窗口工作在一个非UI的线程,如果不加任何处理的话,直接在命令窗口里操作UI物件的引用就会导致一个System.InvalidOperationException: “Object is currently in use elsewhere”(.net 2.0),或者得到一个不可知的状态(.net 1.0)。 [b]应用场景和解决方案[/b] 上面提出的一个很常见问题:应用程序有两个线程:线程A和线程B,不过线程B比较特殊,它属于UI线程,当这两个线程同时运行的时候,线程A有个需求:”修改UI对象的属性”,这时候如果你是线程A,你会如何去完成需求呢?!可能有几种解决方案。 第一种方式: 在线程A上面直接去操作UI对象,这是线程B说:”线程A,你不知道我的特殊嘛!”,然后直接抛给线程A一个InvalidOperationException,线程A得到异常后,一脸的无辜和无奈…..! 第二种方式:   InvokeRequired?!是的,当然没问题。(InvokeRequired属性是每个Control对象都具有的属性,它会返回true和false,当是true的时候,表示它在另外一个线程上面,这是必须通过Invoke,BeginInvoke这些方法来调用更新UI对象的方法,当是false的时候,有两种情况,1:位于当前线程上面,可以通过直接去调用修改UI对象的方法,2:位于不同的线程上,不过控件或窗体的句柄不存在。对于句柄是否存在的判断,可以通过IsHandleCreated来获取,如果句柄不存在,是不能调用Invoke…这些方法的,这时候你必须等待句柄的创建。有点寒) 这些代码对还在使用.NET 1.0下的朋友还是有所帮助的: using System; using System.Drawing; using System.Windows.Forms; using System.Threading;    public class MyFormControl : Form    {       public delegate void AddListItem(String myString);       public AddListItem myDelegate;       private Button myButton; […]

, , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.