非主线程里的this.Invoke会和主线程的Thread.Sleep冲突?

zjnuan 2017-09-19 10:32:11
问题代码如下
bool testboolean = true;
thr = new Thread(() =>
{
this.Invoke(() => { textbox1.Text = 333; });
testboolean = false;
});
thr.IsBackground = true;
thr.Start();
do {
Thread.Sleep(100);
} while (testboolean);

上面代码会卡死不动,非主线程里的this.Invoke会和主线程的Thread.Sleep冲突?Thread.Sleep改为"非主线程.join()"也是卡死。

请问这是什么原因?我的目的就是利用testboolean标志来控制程序的流程控制,请问有什么好的解决方法代替上面的?
...全文
498 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 4 楼 duanzi_peng 的回复:
非主线程里的this.Invoke会和主线程的Thread.Sleep冲突 -》不会,this.invoke 执行与this有关的UI操作。可能是你的testboolean 一直为true。 控制程序的流程控制 -》建议使用Task的ContinueWith。
我感觉是会冲突。在非主线程上完成后,我再例testboolean =false了,不存在一直true。
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 1 楼 zmok8866 的回复:
看一下testboolean是否会正常变为false,是否一直都是true
我目的是在主线程等待非主线程使testboolean变为false。
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 5 楼 hanjun0612 的回复:
不过,你可以使用 begininvoke和endinvoke来完成你的需求
bool testboolean = true;
            Action a = () => { this.textBox1.Text = "3333"; };
            Thread thr = new Thread(() =>
            {
                testboolean = false;
                IAsyncResult asynResult = this.BeginInvoke(a);
                if (asynResult.IsCompleted)
                    testboolean = false;
                
            });
            thr.IsBackground = true;
            thr.Start();
            do
            {
                Thread.Sleep(100);
            } while (testboolean);
我需要将testboolean = false放到非主线程的最后,即也是this.Invoke之后。使用 IAsyncResult也是会死机冲突。 我感觉是非主线程引用this.Invoke之后,如果主线程使用Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone,都会会死机冲突。this.Invoke也是回到主线程工作,是不是这样就和Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone争抢时间片引起冲突?
  • 打赏
  • 举报
回复
引用 10 楼 zjnuan 的回复:
我感觉是非主线程引用this.Invoke之后,如果主线程使用Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone,都会会死机冲突。this.Invoke也是回到主线程工作,是不是这样就和Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone争抢时间片引起冲突?
先不要纠结于什么底层的线程机制,先把高层次的设计模式学会了,以免浑浑噩噩的情况下去“研究”底层的语句。 高层的机制,即使不考虑什么线程概念,即使只用主线程安排你的代码,也可以分时做任意多帧、各种动作,改变各种异步状态。不考虑什么线程概念,而是把 while 之类的坑爹的错误流程设计问题解决掉,能在主线程完成各种事件驱动设计,那么你再来考虑子线程概念才能更真实更敏捷。否则只知道纠结底层概念,你用的那些语句是头脑不清晰目的不明确之下的盲目的“技术”,它其实只会更卡和更乱而少有设计出路。
  • 打赏
  • 举报
回复
比如说你要应聘,同时还要在空闲时去看场电影,请问你会蹲在人家招聘公司门口“死循环”同时还去电影院看场电影吗? 写循环,这是大多数学过几天编程、但是根本没有学会基本编程模式的人的通病。当他要反复做100个事情时,他满脑子就只有写几十个循环语句,从来不会安排事件驱动流程。这其实只有刚学编程时最初级什么简单数学计算函数才会这样顺序、循环的流程。真正的长时间交互的程序都是事件驱动的。你如果不会安排不同时间响应不同事件,那么就算知道了线程概念也是入了一个大坑,写出的代码是恶性循环的地滥用线程、并且滥用死循环和阻塞语句。 稍微专业一点的概念:交互式程序编程设计要基于事件驱动来设计,你画流程图的时候如果不会画出事件驱动,那么你脑子里本身就没有事件。
  • 打赏
  • 举报
回复
不要乱写什么 while 循环,循环的思路本身就代表着卡死的思路。要定时做什么事情,那就用定时器机制!
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 14 楼 jinting2010 的回复:
主线程一直不断sleep,thr线程委托主线程执行的修改textbox文本 则一直在等待,所以也不会执行到testboolean = false; 所以主线程一直在sleep,不建议在主线程sleep
有点明白了。
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 13 楼 sp1234 的回复:
[quote=引用 10 楼 zjnuan 的回复:] 我感觉是非主线程引用this.Invoke之后,如果主线程使用Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone,都会会死机冲突。this.Invoke也是回到主线程工作,是不是这样就和Thread.Sleep或WaitHandle.waitone或AutoResetEvent.waitone争抢时间片引起冲突?
先不要纠结于什么底层的线程机制,先把高层次的设计模式学会了,以免浑浑噩噩的情况下去“研究”底层的语句。 高层的机制,即使不考虑什么线程概念,即使只用主线程安排你的代码,也可以分时做任意多帧、各种动作,改变各种异步状态。不考虑什么线程概念,而是把 while 之类的坑爹的错误流程设计问题解决掉,能在主线程完成各种事件驱动设计,那么你再来考虑子线程概念才能更真实更敏捷。否则只知道纠结底层概念,你用的那些语句是头脑不清晰目的不明确之下的盲目的“技术”,它其实只会更卡和更乱而少有设计出路。[/quote] 这个获益匪浅。我重新架构思路一下。
zjnuan 2017-09-21
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
不要乱写什么 while 循环,循环的思路本身就代表着卡死的思路。要定时做什么事情,那就用定时器机制!
有道理。
jinting2010 2017-09-21
  • 打赏
  • 举报
回复
主线程一直不断sleep,thr线程委托主线程执行的修改textbox文本 则一直在等待,所以也不会执行到testboolean = false; 所以主线程一直在sleep,不建议在主线程sleep
ilikeff8 2017-09-21
  • 打赏
  • 举报
回复
和你的线程没有任何关系,主线程里一直sleep的这个死循环就已经把程序卡死了
秋的红果实 2017-09-20
  • 打赏
  • 举报
回复
this.Invoke也在主线程上。一般是非窗体控件.invoke();
大鱼> 2017-09-20
  • 打赏
  • 举报
回复
你已经委托给UI线程处理你线程的东西了,再Sleep...
正怒月神 2017-09-20
  • 打赏
  • 举报
回复
不过,你可以使用 begininvoke和endinvoke来完成你的需求
bool testboolean = true;
            Action a = () => { this.textBox1.Text = "3333"; };
            Thread thr = new Thread(() =>
            {
                testboolean = false;
                IAsyncResult asynResult = this.BeginInvoke(a);
                if (asynResult.IsCompleted)
                    testboolean = false;
                
            });
            thr.IsBackground = true;
            thr.Start();
            do
            {
                Thread.Sleep(100);
            } while (testboolean);
exception92 2017-09-20
  • 打赏
  • 举报
回复
非主线程里的this.Invoke会和主线程的Thread.Sleep冲突 -》不会,this.invoke 执行与this有关的UI操作。可能是你的testboolean 一直为true。 控制程序的流程控制 -》建议使用Task的ContinueWith。
正怒月神 2017-09-20
  • 打赏
  • 举报
回复
因为你已经this.invoke了, 所以后面testboolean=false;对于主窗体来说,不起作用。
正怒月神 2017-09-20
  • 打赏
  • 举报
回复
先设置testboolean = false;
Action a = () => { this.textBox1.Text = "3333"; };
            Thread thr = new Thread(() =>
            {
                testboolean = false;
                this.Invoke(a);
                
            });
            thr.IsBackground = true;
            thr.Start();
zmok8866 2017-09-20
  • 打赏
  • 举报
回复
看一下testboolean是否会正常变为false,是否一直都是true

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧