Chinaunix首页 | 论坛 | 博客
  • 博客访问: 474301
  • 博文数量: 112
  • 博客积分: 5696
  • 博客等级: 大校
  • 技术积分: 1720
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-17 09:58
文章分类

全部博文(112)

文章存档

2011年(22)

2010年(28)

2009年(21)

2008年(41)

分类: WINDOWS

2009-06-16 11:40:12

今天做一个ui,就是异步调用,然后返回一个string类型的结果,然后再去给textbox,貌似很简单的事情,结果,vs罢工了,说,不是从textbox返回的线程安全!

经过msdn和网络查询


Control.InvokeRequired 属性

获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。


属性值

如果控件的  是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false

Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。

Note注意

除了 InvokeRequired 属性以外,控件上还有以下四个线程安全的方法可供调用:、、 和 。对于所有其他方法调用,当从另一个线程进行调用时,应使用这些 Invoke 方法之一。

如果控件句柄尚不存在,则 InvokeRequired 沿控件的父级链搜索,直到它找到有窗口句柄的控件或窗体为止。如果找不到合适的句柄,InvokeRequired 方法将返回 false

这意味着如果不需要 Invoke(调用发生在同一线程上),或者如果控件是在另一个线程上创建的但尚未创建控件的句柄,则 InvokeRequired 可以返回 false

如果尚未创建控件的句柄,您就不能简单地在控件上调用属性、方法或事件。这可能导致在后台线程上创建控件的句柄,从而隔离不带消息泵的线程上的控件并使应用程序不稳定。

当 InvokeRequired 在后台线程上返回 false 时,您也可以通过检查  的值来避免这种情况。如果尚未创建控件句柄,您必须等到控件句柄已创建,才能调用 Invoke 或 BeginInvoke。通常,仅当在应用程序主窗体的构造函数中创建了后台线程时(如同在Application.Run(new MainForm()) 中),在已经显示窗体或取消 Application.Run 之前,才会发生这种情况。

一种解决方案是等到已经创建了窗体的句柄,然后启动后台线程。通过调用 Handle 属性强制创建句柄,或者等待  事件启动后台进程。

一种更好的解决方案是使用  返回的 SynchronizationContext,而不是使用控件进行线程间封送处理。



    private delegate void UIInvokeCallback(string msg);


        void ftp_OnFtpResponseEvent(object sender, FtpResponseEventArgs e)

        {

            string strResponse = string.Format("响应:{0}\r\n", e.Response.RawText);

            this.MsgCallback(strResponse);

        }


        private void MsgCallback(string msg)

        {

            if (txtInfo.InvokeRequired)

            {

                UIInvokeCallback InvokeCallbackmsgCallback = new UIInvokeCallback(MsgCallback);

                txtInfo.Invoke(InvokeCallbackmsgCallback, msg);

            }

            else

            {

                txtInfo.AppendText(msg);

            }

        }


        void ftp_OnFtpRequestEvent(object sender, FtpRequestEventArgs e)

        {

            string strRequest = string.Format("请求:{0}\r\n",e.Request.Text);

            this.MsgCallback(strRequest);

        }



问题解决!

阅读(1701) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-06-19 00:32:22

http://www.xianyun.info/show.asp?id=92&index