苏飞论坛

标题: C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate [打印本页]

作者: 站长苏飞    时间: 2013-6-6 14:51
标题: C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate
         C#多线程解决界面卡死问题的完美解决方案,BeginInvoke而不是委托delegate
文章下最方有源码下载
   问题描述:
当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决
一个主线程来创建界面,使用一个子线程来执行程序并更新主界面
这样就不会出现卡死的现像了
这肯定是没有问题的,
但是为什么在使用的过程中一样会有很多地方会出现卡死呢,而且有用户跟我说是我的Httphelper类的问题,其实不是,而且我再次声明我的Httphelper类跟多线程并没有关系。不要在诬赖我了哦。
这个问题其实也困或了我很久,但是今天终于解决了,而且我发现很多人有这样的问题,所以我分享一个例子方便大家参考吧。
先来看看我的界面
(, 下载次数: 1739)
当我单击
开始执行后
(, 下载次数: 1655)
这个时候界面是不会卡死的,
只是数据在不断的更新
下面看看我的代码
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //创建一个委托,是为访问TextBox控件服务的。
        public delegate void UpdateTxt(string msg);
        //定义一个委托变量
        public UpdateTxt updateTxt;

        //修改TextBox值的方法。
        public void UpdateTxtMethod(string msg)
        {
            richTextBox1.AppendText(msg + "\r\n");
            richTextBox1.ScrollToCaret();
        }

        //此为在非创建线程中的调用方法,其实是使用TextBox的Invoke方法。
        public void ThreadMethodTxt(int n)
        {
            this.BeginInvoke(updateTxt, "线程开始执行,执行" + n + "次,每一秒执行一次");
            for (int i = 0; i < n; i++)
            {
                this.BeginInvoke(updateTxt, i.ToString());
                //一秒 执行一次
                Thread.Sleep(1000);
            }
            this.BeginInvoke(updateTxt, "线程结束");
        }
        //开启线程
        private void button1_Click(object sender, EventArgs e)
        {
            Thread objThread = new Thread(new ThreadStart(delegate
            {
                ThreadMethodTxt(Convert.ToInt32(textBox1.Text.Trim()));
            }));
            objThread.Start();
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            //实例化委托
            updateTxt = new UpdateTxt(UpdateTxtMethod);
        }
    }
}

就这些代码,大家看注释应该就明白一点了,
主要是使用一个委托来更新界面的richTextBox1
这样写是肯定没有问题的,而且在我其它的更高级一点的例子里也是这么写的
C#多线程|匿名委托传参数|测试网站压力--升级版
http://www.sufeinet.com/thread-13-1-1.html
上面的文件大家可以做为参考
那问题现在那里呢,其实就出在这一句上
[C#] 纯文本查看 复制代码
this.BeginInvoke(updateTxt, "线程结束");

大家也许已经发现了,我是这样写的,而不是
[C#] 纯文本查看 复制代码
updateTxt("线程结束");

这样来直接在子线程中使用,
我相信有很多同志都是这样写的,其实错就错在这里
如果直接使用
[C#] 纯文本查看 复制代码
updateTxt("线程结束");

大家想一下应该就明白了,
updateTxt是在主线程创建的,而我们在子线程中直接使用,运行的数据多了,就会出现卡死,这是界面信息堵死的原因,
所以就算是委托也不能直接在子线程中使用,而是要使用BeginInvoke方法来调用这个委托
这样才不会出现卡死的现像。
问题就解决了。
大家支持一下哦
下面是我的源码提供给大家下载吧
(, 下载次数: 3375)
注意只有注册会员才可以下载(没有通过邮件认证的用户也无法下载)

[groupid=74]sufeinet总群[/groupid]
作者: yangying    时间: 2013-6-6 15:01
沙发,我是第一个来的,支持楼主
作者: ttstudio    时间: 2013-6-6 20:54
这个东西很有用,赶紧收了学习学习
作者: 小学生    时间: 2013-6-7 11:14
菜鸟学习中。。。。
作者: qq576733600    时间: 2013-6-8 08:29
太棒了。 刚好 需要这个 ,找了好多资料,没有实现的了。
作者: 站长苏飞    时间: 2013-6-8 08:33
qq576733600 发表于 2013-6-8 08:29
太棒了。 刚好 需要这个 ,找了好多资料,没有实现的了。

能帮上忙就好,有问题可以来论坛发帖子
作者: 风雅。    时间: 2013-6-20 16:23
回帖留名,以免找不到。。。
作者: mj5lucky    时间: 2013-6-21 10:12
受教了,学习中……
作者: leenkon    时间: 2013-6-22 10:45
支持了。。站长太有分享精神了

作者: Marco    时间: 2013-6-24 17:07
受教了,好东西,学习学习
作者: 爱国爱民小青年    时间: 2013-6-26 11:14
楼主是好人
作者: zhlei1012    时间: 2013-7-30 15:56
数量改的多点,运行后,窗口会拖拽不动
作者: 头文字C    时间: 2013-9-4 22:49
我写了一个TCP服务器程序,需要在接受回调函数里改变Textbox里的内容,需要做啊!我按照你的帖子里的方法写了委托后,将this.BeginInvoke(updateTxt, "线程开始执行,执行" + n + "次,每一秒执行一次");复制到接受回调函数中,编译器提示
错误        2        “TCP.MainWindow”不包含“BeginInvoke”的定义,并且找不到可接受类型为“TCP.MainWindow”的第一个参数的扩展方法“BeginInvoke”(是否缺少 using 指令或程序集引用?)       



作者: pupu123    时间: 2013-10-13 18:18
受教了,学习中……
作者: pureforce    时间: 2013-11-1 09:18
學習了 終於找到一個好的學習 網站
作者: 菩提树    时间: 2013-11-26 23:46
好东西,最好解释一下原理性的东西,方面学习
作者: sandy1231    时间: 2013-12-11 23:03
this.BeginInvoke 是richTextBox.BeginInvoke的意思吗
作者: sandy1231    时间: 2013-12-11 23:22
BeginInvoke和Invoke有什么区别呢
作者: 站长苏飞    时间: 2013-12-12 07:55
sandy1231 发表于 2013-12-11 23:22
BeginInvoke和Invoke有什么区别呢

兄弟这个百度一下有好多的
近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下。感谢这篇文章对我的理解Invoke和BeginInvoke的真正含义
(一)Control的Invoke和BeginInvoke
我们要基于以下认识:
(1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。
(2)Control的Invoke和BeginInvoke的参数为delegate,委托的方法是在Control的线程上执行的,也就是我们平时所说的UI线程。

我们以代码(一)来看(Control的Invoke)
private delegate void InvokeDelegate();
private void InvokeMethod(){
   //C代码段
}
private void butInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   this.Invoke(new InvokeDelegate(InvokeMethod));
   //B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A------>C---------------->B
解释:(1)A在UI线程上执行完后,开始Invoke,Invoke是同步
(2)代码段B并不执行,而是立即在UI线程上执行InvokeMethod方法,即代码段C。
(3)InvokeMethod方法执行完后,代码段C才在UI线程上继续执行。

看看代码(二),Control的BeginInvoke
private delegate void BeginInvokeDelegate();
private void BeginInvokeMethod(){
   //C代码段
}
private void butBeginInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod));
   //B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A----------->B--------------->C慎重,这个只做参考。。。。。,我也不肯定执行顺序,如果有哪位达人知道的话请告知。
解释::(1)A在UI线程上执行完后,开始BeginInvoke,BeginInvoke是异步
(2)InvokeMethod方法,即代码段C不会执行,而是立即在UI线程上执行代码段B。
(3)代码段B执行完后(就是说butBeginInvoke_Click方法执行完后),InvokeMethod方法,即代码段C才在UI线程上继续执行。

由此,我们知道:
Control的Invoke和BeginInvoke的委托方法是在主线程,即UI线程上执行的。也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死。

那么,这个异步到底是什么意思呢?

异步是指相对于调用BeginInvoke的线程异步,而不是相对于UI线程异步,你在UI线程上调用BeginInvoke ,当然不行了。----摘自"Invoke和BeginInvoke的真正涵义"一文中的评论。
BeginInvoke的原理是将调用的方法Marshal成消息,然后调用Win32 API中的RegisterWindowMessage()向UI窗口发送消息。----摘自"Invoke和BeginInvoke的真正涵义"一文中的评论。

(二)我们用Thread来调用BeginInvoke和Invoke
      我们开一个线程,让线程执行一些耗费时间的操作,然后再用Control.Invoke和Control.BeginInvoke回到用户UI线程,执行界面更新。

代码(三)  Thread调用Control的Invoke
private Thread invokeThread;
private delegate void invokeDelegate();
private void StartMethod(){
   //C代码段......
   Control.Invoke(new invokeDelegate(invokeMethod));
  //D代码段......
}
private void invokeMethod(){
  //E代码段
}
private void butInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   invokeThread = new Thread(new ThreadStart(StartMethod));
   invokeThread.Start();
   //B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A------>(Start一开始B和StartMethod的C就同时执行)---->(C执行完了,不管B有没有执行完,invokeThread把消息封送(invoke)给UI线程,然后自己等待)---->UI线程处理完butInvoke_Click消息后,处理invokeThread封送过来的消息,执行invokeMethod方法,即代码段E,处理往后UI线程切换到invokeThread线程。
这个Control.Invoke是相对于invokeThread线程同步的,阻止了其运行。

解释:
1。UI执行A
2。UI开线程InvokeThread,B和C同时执行,B执行在线程UI上,C执行在线程invokeThread上。
3。invokeThread封送消息给UI,然后自己等待,UI处理完消息后,处理invokeThread封送的消息,即代码段E
4。UI执行完E后,转到线程invokeThread上,invokeThread线程执行代码段D

代码(四)  Thread调用Control的BeginInvoke
private Thread beginInvokeThread;
private delegate void beginInvokeDelegate();
private void StartMethod(){
   //C代码段......
   Control.BeginInvoke(new beginInvokeDelegate(beginInvokeMethod));
  //D代码段......
}
private void beginInvokeMethod(){
  //E代码段
}
private void butBeginInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   beginInvokeThread = new Thread(new ThreadStart(StartMethod));
   beginInvokeThread .Start();
   //B代码段......
}
你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上
A在UI线程上执行----->beginInvokeThread线程开始执行,UI继续执行代码段B,并发地invokeThread执行代码段C-------------->不管UI有没有执行完代码段B,这时beginInvokeThread线程把消息封送给UI,单自己并不等待,继续向下执行-------->UI处理完butBeginInvoke_Click消息后,处理beginInvokeThread线程封送过来的消息。

解释:
1。UI执行A
2。UI开线程beginInvokeThread,B和C同时执行,B执行在线程UI上,C执行在线程beginInvokeThread上。
3。beginInvokeThread封送消息给UI,然后自己继续执行代码D,UI处理完消息后,处理invokeThread封送的消息,即代码段E
有点疑问:如果UI先执行完毕,是不是有可能过了段时间beginInvokeThread才把消息封送给UI,然后UI才继续执行封送的消息E。如图浅绿的部分。


Control的BeginInvoke是相对于调用它的线程,即beginInvokeThread相对是异步的。
因此,我们可以想到。如果要异步取耗费长时间的数据,比如从数据库中读大量数据,我们应该这么做。
(1)如果你想阻止调用线程,那么调用代码(三),代码段D删掉,C改为耗费长时间的操作,因为这个操作是在另外一个线程中做的。代码段E改为更新界面的方法。
(2)如果你不想阻止调用线程,那么调用代码(四),代码段D删掉,C改为耗费长时间的操作,因为这个操作是在另外一个线程中做的。代码段E改为更新界面的方法。

相关知识:1。Invoke 和 BeginInvoke 的真正涵义


作者: sandy1231    时间: 2013-12-12 19:57
飞哥这不是多线程吧,只是一个线程中N次执行,刚在任务管理器看了下 ,执行的时候只多了一个线程。这样界面是不会假死,但我发现我这样写会假死:
[C#] 纯文本查看 复制代码
for (int i = 0; i < 100; i++)
            {
                Thread red = new Thread(new ThreadStart(delegate
                    {
                        Fabu();
                    }));
                red.Start();
            }                  


用BeginInvoke也一样。




C#多线程|匿名委托传参数|测试网站压力--升级版
http://www.sufeinet.com/thread-13-1-1.html
看了飞哥的例子 运行了一下  开启多线程后拖动界面也同样是假死
有解决方法吗飞哥


作者: 夜雨蒙蒙    时间: 2014-2-19 14:16
楼主很强大,学习了!!
作者: tian2010    时间: 2014-3-19 08:26
支持一下!
作者: 暗夜孤荧    时间: 2014-3-27 12:19
  Application.DoEvents();
用哪种委托都一样,这个还是要加的,不然照样会卡死的
作者: 龟宝宝    时间: 2014-5-8 09:04
[C#] 纯文本查看 复制代码
   public Form1()
        {
            InitializeComponent();
        }
        //创建一个委托,是为访问TextBox控件服务的。
        public delegate void UpdateTxt(string msg);
        //定义一个委托变量
        public UpdateTxt updateTxt;

        Thread objThread;


        //修改TextBox值的方法。
        public void UpdateTxtMethod(string msg)
        {
            richTextBox1.AppendText(msg + "\r\n");
            richTextBox1.ScrollToCaret();
        }

        //此为在非创建线程中的调用方法,其实是使用TextBox的Invoke方法。
        public void ThreadMethodTxt(int n)
        {
            while (!this.IsHandleCreated)
            {
            }
            this.BeginInvoke(updateTxt, "线程开始执行,执行" + n + "次,每一秒执行一次");
            for (int i = 0; i < n; i++)
            {
                while (!this.IsHandleCreated)
                {

                }
                this.BeginInvoke(updateTxt, i.ToString());
                //一秒 执行一次
                Thread.Sleep(1000);
            }
            this.BeginInvoke(updateTxt, "线程结束");
        }
        //开启线程
        private void button1_Click(object sender, EventArgs e)
        {
            objThread = new Thread(new ThreadStart(delegate
             {
                 ThreadMethodTxt(Convert.ToInt32(textBox1.Text.Trim()));
             }));
            objThread.Start();
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            //实例化委托
            updateTxt = new UpdateTxt(UpdateTxtMethod);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            
            objThread.Abort();
        }

作者: shmily0923    时间: 2014-5-13 15:55
2ms更新一次时,拖动窗口会偶尔卡死。
作者: wkpeng    时间: 2014-5-15 09:48
这金钱上哪赚?
作者: 站长苏飞    时间: 2014-5-15 09:50
wkpeng 发表于 2014-5-15 09:48
这金钱上哪赚?

每天登录,签到,发帖子发回复都会送的,你选择你的用户组的介绍的。
作者: xxooxx    时间: 2014-5-21 19:01
这么好的贴子应该支持, 强烈支持楼主ing……论坛能有几个像飞哥这样的,新来的有福了!
作者: sway913    时间: 2014-5-23 10:31
受教了,好东西,学习学习
作者: pivyang    时间: 2014-6-11 22:08
强烈支持楼主ing……线程操作,必须学习
作者: zhujunxxxxx    时间: 2014-6-14 13:51
感觉在这里可以学到好多东西啊,热爱C#
作者: 我是谁    时间: 2014-7-7 08:56
受教了,学习中……
作者: Cheungnotes    时间: 2014-7-10 16:57
真是难得给力的帖子啊,强烈支持楼主。
作者: clown31    时间: 2014-7-26 17:53
多谢 好东西
作者: 啊Q皇弟    时间: 2014-8-1 22:41
支持一下 非常好的文章
作者: Kvkens    时间: 2014-9-23 15:37
受教了学习中……
作者: BigCodeMan    时间: 2014-9-24 10:30
站长一直是赠人玫瑰,手有余香啊!!
作者: asp.net0610    时间: 2014-10-8 10:47
学习了,留个名
作者: ching126    时间: 2014-10-8 12:20
强烈支持楼主ing……
作者: 精彩    时间: 2014-11-21 06:49
做采集和群发的迟早是要掌握多线程的
作者: ld4317014    时间: 2014-11-28 13:12
以前此问题也一直困扰着我
作者: haibuo1981    时间: 2015-1-9 11:37
路过,顺便说一句,Invoke 和BeginInvoke的本质同步和异步的区别,适应于不同场景。
Delegate.Invoke: Executes synchronously, on the same thread.
Delegate.BeginInvoke: Executes asynchronously, on a threadpool thread.
Control.Invoke: Executes on the UI thread, but calling thread waits for completion before continuing.
Control.BeginInvoke: Executes on the UI thread, and calling thread doesn't wait for completion.

作者: 我是MT    时间: 2015-1-25 00:25
这个方法用在dataGridView中貌似不行哦。还是一样的卡死界面,只能等到数据全部处理完才能不卡。
作者: 站长苏飞    时间: 2015-1-25 08:33
我是MT 发表于 2015-1-25 00:25
这个方法用在dataGridView中貌似不行哦。还是一样的卡死界面,只能等到数据全部处理完才能不卡。

我这边没有这种情况,是不是和你的代码有关系
作者: 我是MT    时间: 2015-1-26 17:51
如果是post获取网页信息的时候,界面卡死了怎么解决呢。
作者: 纳兰小寒    时间: 2015-2-12 14:58
收藏了,过年时候好好学一下C#
作者: 龍游天下    时间: 2015-3-12 11:52
如果提前关闭窗口,则出错:在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。
作者: 站长苏飞    时间: 2015-3-13 08:27
龍游天下 发表于 2015-3-12 11:52
如果提前关闭窗口,则出错:在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。

处理下异常,这是因为还有数据没有更新的原因,或者是线程没有结束就先关闭了应用程序
作者: 755677892    时间: 2015-4-11 17:02
强烈支持楼主ing……
作者: 神同步    时间: 2015-7-22 21:11
其实我喜欢在多线程的时候对主线程窗体的控件这样赋值  懒得写委托 要是有十个组件是个蛋疼的事
     
this.Invoke(new Action(() =>
                   {
                      textbox.Text="更新了";
                   }));

作者: 站长苏飞    时间: 2015-7-23 08:13
神同步 发表于 2015-7-22 21:11
其实我喜欢在多线程的时候对主线程窗体的控件这样赋值  懒得写委托 要是有十个组件是个蛋疼的事
     
...

写个统一的就行了,或者写个方法出来,传对象过来
作者: rund11    时间: 2015-7-29 17:02
膜拜中....!
作者: barretq    时间: 2015-8-3 00:24
谢谢飞哥,很有用!!
作者: 风雷之冰    时间: 2015-8-21 16:17
受教了学习中……
作者: iguige    时间: 2015-10-30 20:58
受教了学习中……
作者: jsrgwjj    时间: 2015-11-2 20:08
好东西,正好需要!!!!
作者: taoerchun    时间: 2015-11-11 10:31
你不用Invoke直接更新richTextBox1的话会报“不是从它创建的线程访问”的错吧
作者: 站长苏飞    时间: 2015-11-11 10:40
taoerchun 发表于 2015-11-11 10:31
你不用Invoke直接更新richTextBox1的话会报“不是从它创建的线程访问”的错吧

你猜的吧,我运行这么久也没听说过会有这错
作者: taoerchun    时间: 2015-11-11 12:55
站长苏飞 发表于 2015-11-11 10:40
你猜的吧,我运行这么久也没听说过会有这错

我下载了你的源码,取消掉BeginInvoke后报“线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。”
作者: 站长苏飞    时间: 2015-11-11 13:23
taoerchun 发表于 2015-11-11 12:55
我下载了你的源码,取消掉BeginInvoke后报“线程间操作无效: 从不是创建控件“richTextBox1”的线程访问 ...

我去,这不用说肯定是不行啊,你上面写的Invoke  而不是BeginInvoke 这有本质区别,我上面以为你说的不用Invoke  会出问题
作者: 雨之秋水    时间: 2015-11-12 14:00
受教了学习中…… 简单的例子学习下 了解大概的了
作者: sn99206    时间: 2015-12-24 10:35
谢谢,正遇到这问题
作者: 馨雨科技    时间: 2015-12-27 10:08
站长苏飞 发表于 2013-6-8 08:33
能帮上忙就好,有问题可以来论坛发帖子

我用ListView 全部都是一样的代码 只是把控件换成了 ListView 依旧还是假死 很奇怪 明明 我也是 在 Thread中 使用  this.BeginInvoke()  应该是在子线程中调用委托的啊 ?  但是还是卡死界面
作者: 站长苏飞    时间: 2015-12-27 12:13
馨雨科技 发表于 2015-12-27 10:08
我用ListView 全部都是一样的代码 只是把控件换成了 ListView 依旧还是假死 很奇怪 明明 我也是 在 Threa ...

发个帖子出来看看具体情况
作者: 馨雨科技    时间: 2016-1-16 22:36
站长苏飞 发表于 2015-12-27 12:13
发个帖子出来看看具体情况

不好意思 一直有事情在忙 刚刚上论坛 才看到 现在基本解决了 用的虚拟模式 我上网查了 好像是说是ListView插入的时候 会刷新界面 结果就卡死了 因为我要是在多线程里面加个延时 就不会卡住了 但是速度就慢下来了
作者: 站长苏飞    时间: 2016-1-18 08:45
馨雨科技 发表于 2016-1-16 22:36
不好意思 一直有事情在忙 刚刚上论坛 才看到 现在基本解决了 用的虚拟模式 我上网查了 好像是说是ListVie ...

恩好,如果再有问题可以直接发帖子。
作者: 馨雨科技    时间: 2016-1-19 01:26
站长苏飞 发表于 2016-1-18 08:45
恩好,如果再有问题可以直接发帖子。

请问下  ListView虚拟模式下 还能再修改列表的值吗?  我现在是修改了 绑定的虚拟列表数据 但是修改完以后 必须下拉下列表才行 再返回去修改的那个值 才会显示出来
作者: darenkong    时间: 2016-3-8 04:04
强烈支持楼主ing……
作者: 含羞草草    时间: 2016-4-18 14:57
挺好的,谢谢
作者: tony601818    时间: 2016-5-2 13:17
比一般的资料有用多了
作者: 王二狗    时间: 2016-7-8 14:09
学习了,多线程用委托给datagridview写数据老是卡死,现在用用飞哥的方法试试
作者: 站长苏飞    时间: 2016-7-8 14:34
王二狗 发表于 2016-7-8 14:09
学习了,多线程用委托给datagridview写数据老是卡死,现在用用飞哥的方法试试

这个方法应该是要吧解决的,我亲身测试过,以前写的也是卡
作者: MeeSii    时间: 2016-9-8 00:56
为什么我测试用万能框架获取数据就会卡住啊,完全按你的代码写的呀。
作者: 站长苏飞    时间: 2016-9-8 10:29
MeeSii 发表于 2016-9-8 00:56
为什么我测试用万能框架获取数据就会卡住啊,完全按你的代码写的呀。

具体问题具体分析,发个帖子贴下相关代码出来看下情况
作者: MeeSii    时间: 2016-9-8 14:02
站长苏飞 发表于 2016-9-8 10:29
具体问题具体分析,发个帖子贴下相关代码出来看下情况

我理解错了,应该把操作UI写到委托里面
延迟的操作不能再委托里面
作者: dyyyj    时间: 2018-6-30 09:57

作者: 1229203497    时间: 2018-12-4 08:58
问题已解决 赞一个先
  但是后期出现一个问题  线程未关闭
System.InvalidOperationException:“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”
这个该怎么解决?
作者: 站长苏飞    时间: 2018-12-4 09:22
1229203497 发表于 2018-12-4 08:58
问题已解决 赞一个先
  但是后期出现一个问题  线程未关闭
System.InvalidOperationException:“ ...

不调试没有问题吧
作者: wulincheng    时间: 2018-12-11 16:41
需要看看。。。。。。。。。。。
作者: 竹林风    时间: 2018-12-11 17:41
感恩无私的分享与奉献
作者: Tomato    时间: 2019-1-10 09:11
路过,学习学习
作者: jacksonwong    时间: 2019-5-31 16:44
支持支持支持
作者: lygy8817    时间: 2019-7-5 11:15

受教了,学习中……
作者: Yukee    时间: 2020-4-25 00:12
好知识,学习了
作者: 不苦小和尚    时间: 2020-5-24 12:36
学习了,好多教程里都是说调用beginINvoke
作者: qinxiangwu    时间: 2020-6-11 19:29
我只是路过打酱油的。
作者: atgu2je    时间: 2020-9-5 14:02
留名,以防找不到
作者: bbettry    时间: 2020-9-14 09:35
学习了,谢谢!
作者: livehu5188    时间: 2021-8-15 13:51
谢谢楼主分享啊 谢谢啊
作者: 浮生    时间: 2023-8-22 23:05
没事就回来看看,希望站一直在,在这解决了好多问题了




欢迎光临 苏飞论坛 (http://www.sufeinet.com/) Powered by Discuz! X3.4