精华内容
下载资源
问答
  • 之前在做winform应用的时候,使用多线程控制界面上控件信息,时常碰到InvalidOperationException这个异常!这个异常的出现多数情况是由于worker线程(子线程)修改主线程控件(或对象)的属性而导致的非法操作。这是因为...

      之前在做winform应用的时候,使用多线程控制界面上控件信息,时常碰到InvalidOperationException这个异常!这个异常的出现多数情况是由于worker线程(子线程)修改主线程控件(或对象)的属性而导致的非法操作。这是因为.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性。参照网上的例子,自己总结了一下解决的方法:

       一.我们在窗体加载的时候Form1_Load()方法中加一句代码:

    private void TESTThreadForm _Load(object sender, EventArgs e)
    {
    Control.CheckForIllegalCrossThreadCalls = false;
    Thread thread = new Thread(ThreadFunc);
    thread.IsBackground = true;
    thread.Start();
    }

       加入这句代码以后发现程序可以正常运行了。这句代码就是说在这个类中我们不检查跨线程的调用是否合法(如果没有加这句话运行也没有异常,那么说明系统以及 默认的采用了不检查的方式)。然而,从安全性方面看,这种方法不可取。CheckForIllegalCrossThreadCalls容许子线程随时更新ui,在同一个函数体内,不能保证自身事务的一致性。如给lable赋值,可能一回头,就已经给别人修改了,当然你可以自己加锁,用信号量,但工作量又多了,而且如果在项目中多处需要跨纯种访问控件,那就要重复又重复添加!我们要采取另外的方案。

      二.方案二是使用delegate和invoke来从其他线程中控制控件信息。

    public partial class TESTThreadForm : Form
    {
    private delegate void ProxyClient();//代理
    public Form1()
    {
    InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
    Thread thread = new Thread(CrossThreadFlush);
    thread.IsBackground = true;
    thread.Start();
    }
    private void CrossThreadFlush()
    {
    while (true)
    {
    //将sleep和无限循环放在等待异步的外面
    Thread.Sleep(1000);
    ThreadFunction();
    }
    }
    private void ThreadFunction()
    {
    if (this.textBox1.InvokeRequired)//等待异步
    {
    FlushClient fc = new ProxyClient(ThreadFunction);
    this.Invoke(fc);//通过代理调用刷新方法
    }
    else
    {
    this.textBox1.Text = DateTime.Now.ToString();
    }
    }
    }

      用第二种方案,我们可以解决了跨纯种访问控件的属性和信息,通过等待异步,不需要总是持有主线程的控制,这样就可以在不发生跨线程调用异常的情况下完成多线程对winform多线程控件的控制了。

    转载于:https://www.cnblogs.com/Michael-Kong/archive/2012/05/29/2524807.html

    展开全文
  • 背景 在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作。他们会引发软件的卡顿甚至假死,严重影响软件的使用...在子线程中修改界面控件时Visual Studio会报出如下错误: 解决思路 .Net提供了很多跨..

    背景

    在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作。他们会引发软件的卡顿甚至假死,严重影响软件的使用。因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程(UI线程)与用户间的交互。但多个线程竞争读写同一个资源往往会造成意想不到的意外结果,UI界面也是一种资源,所以跨线程修改UI界面往往被加以限制。而在Winform中,跨线程修改UI界面同样是不被允许的。在子线程中修改界面控件时Visual Studio会报出如下错误:

     

     

    解决思路

    .Net提供了很多跨线程修改UI的方法,每种方法也有与之对应的工具类。我最常用的方法是ThreadPool+ delegate的方式完成跨线程对UI对的修改。

    实例代码

    1、定义委托,把内容写在控件里面

    复制代码

     private delegate void SetLabelDelegate(string value);
    
            private delegate void SetLabelDelegate2(string value);
    
            private void SetText(string value)
            {
                if (this.InvokeRequired)
                {
                    SetLabelDelegate d = new SetLabelDelegate(SetText);
                    this.Invoke(d, new object[] { value });
                }
                else
                {
                    txtbigcrmresult.Text = value.ToString() + txtbigcrmresult.Text;
                }
            }

    复制代码

     

    
     

    2、定义方法,线程调用

    复制代码

    private void button3_Click(object sender, EventArgs e)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(dao), "test");
            }
      private void dao(object url)
            {
                IDbConnection conn = new SqlConnection(txtbigcrmui.Text);
                SetText("\r\n" + "start");
              .........................
                SetText("\r\n" + "end");
            }

    复制代码

     

     

    3、更新ui控件 

     SetText("\r\n" + "start");

     

     

    总结

    1、使用delegate实现跨线程更新UI;

    2、使用ThreadPool实现多线程执行方法,避免卡顿;

     

    展开全文
  • 背景在我做WinForm开发的过程,经常会遇到耗时操作或阻塞操作。他们会引发软件的卡顿甚至假死,严重影响软件的使用。因此,这类耗时或阻塞的操作一般都会...而在Winform中,跨线程修改UI界面同样是不被允许的。...

    背景

    在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作。他们会引发软件的卡顿甚至假死,严重影响软件的使用。因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程(UI线程)与用户间的交互。但多个线程竞争读写同一个资源往往会造成意想不到的意外结果,UI界面也是一种资源,所以跨线程修改UI界面往往被加以限制。而在Winform中,跨线程修改UI界面同样是不被允许的。在子线程中修改界面控件时Visual Studio会报出如下错误:

    a1cfaf95e5cef546dd00bf2fb727ff74.png

    解决思路

    .Net提供了很多跨线程修改UI的方法,每种方法也有与之对应的工具类。我最常用的方法是ThreadPool+ delegate的方式完成跨线程对UI对的修改。

    实例代码

    1、定义委托,把内容写在控件里面

       private delegate void SetLabelDelegate(string value);        private delegate void SetLabelDelegate2(string value);        private void SetText(string value)        {            if (this.InvokeRequired)            {                SetLabelDelegate d = new SetLabelDelegate(SetText);                this.Invoke(d, new object[] { value });            }            else            {                txtbigcrmresult.Text = value.ToString() + txtbigcrmresult.Text;            }        }

    2、定义方法,线程调用

      private void button3_Click(object sender, EventArgs e)        {            ThreadPool.QueueUserWorkItem(new WaitCallback(dao), "test");        }
      private void dao(object url)        {            IDbConnection conn = new SqlConnection(txtbigcrmui.Text);            SetText("\r\n" + "start");          .........................            SetText("\r\n" + "end");        }

    3、更新ui控件 

     SetText("\r\n" + "start");

    总结

    1、使用delegate实现跨线程更新UI;

    2、使用ThreadPool实现多线程执行方法,避免卡顿;

    24c0ccf08fee1d294a5f661a7e2e3446.png

    展开全文
  • vs2005 ,工作线程操作 界面线程的时候,一般会报个错误,叫 么子 工作线程不能够修改主线程什么的。解决方法参考如下: #region 重新加载树图 /// <summary> /// 重新加载树图 /// </summary&...

    vs2005 中,工作线程 操作 界面的线程的时候,一般会 报个错误,叫 么子 工作线程不能够修改主线程什么的。解决方法参考如下:

     #region 重新加载树图
            /// <summary>
            /// 重新加载树图
            /// </summary>
            private void RedrawTree()
            {
                if (treeView1.InvokeRequired)
                {
                    treeView1.Invoke(new MethodInvoker(RedrawTree));
                    return;
                }
                 //ToDo 对界面控件的修改

                }
            }

    还有种:

    Invoke(new MethodInvoker(BeginLoad), null);//适合没有参数的函数

    还有种,是用事件

      #region 设置节点的数据
            delegate void SetNodeValuesDelegate(TreeNode node, TreeItem item);
            /// <summary>
            /// 设置节点的数据
            /// </summary>
            /// <param name="node"></param>
            /// <param name="item"></param>
            private void SetNodeValues(TreeNode node, TreeItem item)
            {
                if (treeView1.InvokeRequired)
                {
                    treeView1.Invoke(new SetNodeValuesDelegate(SetNodeValues), node, item);
                    return;
                }
    // ToDo 对界面控件的修改         

            }

    一些原理文章,参考:

    http://tag.csdn.net/tag/invokerequired/1.html

    http://blog.csdn.net/Depraved_Survival/archive/2007/09/03/1770950.aspx

    http://www.yesky.com/20030225/1653758.shtml

    http://www.x2blog.cn/jinhong618/?tid=22389

     

    以下是wpf中遇到的问题:

    首先,参考文章:http://www.cnblogs.com/zhouyinhui/archive/2007/09/16/894719.html

    转载于:https://www.cnblogs.com/yanchanggang/archive/2007/12/14/995218.html

    展开全文
  • https://blog.csdn.net/lgj123xj/article/details/78533400 待解决的问题 在我做WinForm开发的过程,经常会遇到耗时操作或阻塞操作。他们会引发软件的卡顿甚至假死,严重影响软件的使用。 因
  • c# winform编程之多线程ui界面资源修改总结篇 单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么做,比如:private void ...
  • 单线程的winfom程序中,设置一个控件的值是很easy的事情,...就搞定了,但是如果在一个新线程中这么做,比如:private void btnSet_Click(object sender, EventArgs e){ Thread t = new Thread(new ParameterizedTh...
  • 如果我们在线程中直接修改控件状态和信息那么则会出现如下错误: 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThread 解决方法为,所有需要改变控件状态的都是用委托...
  • winform开发过程经常遇到使用异步线程修改界面的情况,这个时候会报一个跨线程操作的错误,这个时候需要Invoke方式 if (this.InvokeRequired) { this.Invoke(new Action(() => { // 具体的方法内容 这里...
  • WinForm中线程问题?

    2014-08-08 11:46:42
    界面中有一TextBox控件,名为txtName,需要修改其Enabled属性值,用到了多线程+委托,但是程序报错:“线程间操作无效,不能从创建此线程之外的线程访问”,具体代码如下: private void SetStatus() {  this....
  • 使用线程池进行多线程操作 ThreadPool.QueueUserWorkItem((state) => { ...... }); 在多线程中修改UI界面 Form form; //指定form窗口 form.Invoke((EventHandler)delega...
  • 串口汉字编码功能 关于串口线程和汉字编码的使用,一样创建两个窗体给定一定需要的控件: ...界面可以修改更加美化,也可以添加更多的功能,在串口通讯可以实时发送消息,要使用到线程很重要!! ...
  • C# winform线程操作UI exception 在我们做WinForm开发的过程,经常会遇到耗时...但多个线程竞争读写同一个资源往往会造成意想不到的意外结果,UI界面也是一种资源,所以跨线程修改UI界面往往被加以限制。 ...
  • winform程序使用线程的必要性: 单线程操作在执行耗时任务时会造成界面假死,带来非常差劲的用户体验,有时候甚至会影响到正常的业务执行,使用多线程做相关操作实属不得已之举。 那么在编写程序之前必须要明白...
  • 而事件在逻辑处理可能由不同的线程引发,这些事件的响应方法在修改界面中的控件内容时便会引发一个异常。这时就用到了Control.InvokeRequired 属性 与Invoke方法。MSDN说:获取一个值,该值指示调用方在对控件...
  • C#多线程操作界面控件的解决方案

    千次阅读 2014-04-14 14:37:06
     在.Net2.0环境上开发WinForm程序,当在多线程中修改界面控件的状态,会抛出一个异常:Cross-thread operation not valid:Control 'textBox1' accessed from a thread other than the thread it was...
  • 有时候我们会按照特定需要...选择窗体,在属性栏中修改其Language属性,此时用户界面的Localizable属性也已经被调整为true; 然后编辑该区域性语言的本地化资源,即各个控件的可本地化的所有属性都可以,并保存; pr
  • Winform 技巧

    2009-07-16 10:02:00
    而事件在逻辑处理可能由不同的线程引发,这些事件的响应方法在修改界面中的控件内容时便会引发一个异常。 这时就用到了Control.InvokeRequired 属性 与Invoke方法。 MSDN说:获取一个值,该值指示调用方在对...

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

winform线程中修改界面