C#后台线程操作主线程控件

2015-12-04 12:58:15
请问,我在后台线程中,操作UI线程的控件,用了Invoke,程序运行了10多个小时没问题,但是10多小时候会随机出现界面未响应的情况,然后卡死,这是什么原因?换成Beginvoke是不是可以解决?


如下 一:
//获取异步线程的回调结果
IAsyncResult result = this.BeginInvoke
(
new MethodInvoker
(
delegate
{
//操作UI线程控件
}
)
);
///无限期等待任务完成
result.AsyncWaitHandle.WaitOne(-1);
//结束异步
this.EndInvoke(result);


图 二:


this.Invoke
(
new MethodInvoker
(
delegate
{
//操作UI线程控件
}
)
);



这俩者有何区别?哪个更好? 如果想解决堵塞问题,用哪个好?
...全文
246 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
2015-12-04
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
你可以看到,“想解决堵塞问题”,应该写出根本就是无阻塞的程序。而你的设计思路,如果本来就是阻塞式的思路,那么应该从思路上找原因。 你的“图一”和“图二”,都丝毫没有表现出你如何写出无阻塞的程序的思路,因此其实你贴出的两个代码都无用。
一语惊醒梦中人!高手厉害!我一直想寻找这样的办法,却找不到!一直看网上很多例子都是在堵塞线程来虚假的异步完成,我自己看着也别扭,但是局限于见识少,也没想出什么办法,今天试试你的,多谢哥们。
  • 打赏
  • 举报
回复
你可以看到,“想解决堵塞问题”,应该写出根本就是无阻塞的程序。而你的设计思路,如果本来就是阻塞式的思路,那么应该从思路上找原因。 你的“图一”和“图二”,都丝毫没有表现出你如何写出无阻塞的程序的思路,因此其实你贴出的两个代码都无用。
  • 打赏
  • 举报
回复
最容易因为“一颗老鼠屎坏了一锅汤”的做法就是类似 无限期等待任务完成 结束异步 这类说法在作祟。你这是在使用异步的编程语法,偷运着同步、阻塞的实际行为。当你稍微不注意的时候(例如这段代码本身就不小心跑到主线程去执行的时候),就会造成死锁。即使不是这样,仅仅是占用线程在那里死等,当这类代码比较多的时候,因为滥用线程去进行死等操作,也会让计算机的响应变慢、内存耗尽。windows下每一个线程就算你什么都不干也都要占用至少1M内存,需要占用cpu调度时间,绝不能蓝用线程。 应该在“界面上显示数据”才占用(系统线程池分配的一个)线程去处理剩余的操作,而不是让当前线程在那里死等什么结果。
  • 打赏
  • 举报
回复
这两种方法显然都是阻塞的方法,都不好。 一个异步地方法是这样的
ctrl.BeginInvoke((Action)delegate
{
    //在界面上显示数据
    //干剩下的、其它的事情
});
}
或者
ctrl.BeginInvoke((Action)delegate
{
    //在界面上显示数据
    ThreadPool.QueueUserWorkItem(h =>
                {
        //干剩下的、其它的事情
    });
});
这样在BeginInvoke之后就不阻塞,不额外占用当前线程了。
lvfeng_95 2015-12-04
  • 打赏
  • 举报
回复
SynchronizationContext 用这个来同步线程,就可以了 SynchronizationContext syn; public Form1() { InitializeComponent(); syn = WindowsFormsSynchronizationContext.Current; } private void Form1_Load(object sender, EventArgs e) { } private void sound_LoadCompleted() { syn.Post(P => { //操作主线程控件 }, null); } 楼主记得给分啊
Poopaye 2015-12-04
  • 打赏
  • 举报
回复
你怎么确定UI卡住是Invoke的关系?
2015-12-04
  • 打赏
  • 举报
回复
快来点人讨论下
2015-12-04
  • 打赏
  • 举报
回复
引用 1 楼 diaodiaop 的回复:
非UI线程操作UI控件.我只用

xxoo.Invoke(new action(()=>{
 xxoo.text="aaa";
}));
运行几个月 没问题
请问这个跟图中的new MethodInvoker有什么区别吗?我试试你的看看
  • 打赏
  • 举报
回复
这个就凭这几句话,还真没法知道什么问题
by_封爱 版主 2015-12-04
  • 打赏
  • 举报
回复
非UI线程操作UI控件.我只用

xxoo.Invoke(new action(()=>{
 xxoo.text="aaa";
}));
运行几个月 没问题

110,571

社区成员

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

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

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