但是在线程中给界面赋值总是 报错。怎么样解决。界面不假死,不是单纯后台不假死。
Control.CheckForIllegalCrossThreadCalls = false;
用这个可以达到预期想要的效果,但是不安全,一旦用到复杂的代码怕报错,所以不想用这种方式。
假如 Control.CheckForIllegalCrossThreadCalls = true; 给某些界面控件赋值的时候就会报错。
问一下怎么样实现处理界面的时候可以赋值,并且界面不是假死状态。
注意:本人是用多线程是处理主界面,例如 txtBox = “100000”; (例如 这个操作需要3秒,这个代码执行的时候界面不能假死,打个比方而已)。
delegate void AsyncGetDataDelegate();
//在线程里处理代码
private void GetData()
{
PeelerssPoDetail peerpodtil = new PeelerssPoDetail();
DataTable db = peerpodtil.GetPoDtilList(ParmFilter());
dgvData.DataSource = db; //这个过程不能假死
}
private void btnAny_Click(object sender, EventArgs e)
{
try
{
//执行异步线程
AsyncGetDataDelegate adl = new AsyncGetDataDelegate(GetData);
adl.BeginInvoke(new AsyncCallback(GetResult), adl);
}
catch
{
}
}
至于为什么要这种效果这是另一回事,只想解决界面赋值的时候不假死!
3
1
private void btnAny_Click(object sender, EventArgs e)
{
try
{
//执行异步线程
AsyncGetDataDelegate adl = new AsyncGetDataDelegate(GetData);
adl.BeginInvoke(new AsyncCallback(GetResult), adl);
}
catch
{
}
}
其实是毫无意义的,而且它肯定比直接从 UI 线程调用更慢。你这个是使用了异步多线程操作的语法,里模拟一个同步调用过程。虽然你的 btnAny_Click 立刻就结束了,但是你的整个操作都注册到 UI 主线程去排队,然后仍然在主线程去执行。你这就相当于一个在超市收银台付款的人从排队的第一位跑回了队尾重新排队,却自认为本人跑到另外一个空闲的队列中了!这不更慢嘛!
一个正常的多线程编程,是把大量时间用在子线程处理数据操作上,例如1秒钟来处理数据。然后一瞬间(例如5毫秒)输出界面操作的语句注册给 UI 线程去执行。而你这种把全部操作都注册给 UI 主线程的做法,画蛇添足,更慢。
1
为了提高用户体验,用时较长的操作放到单独线程中去,
防止阻塞主线程,界面长时间无响应,
后台处理完成后,通过委托来与UI交互
1
相似 界面要不停的动那种!同时执行。
在主线程排队?仍然在主线程去执行?
那不对啊,Control.CheckForIllegalCrossThreadCalls = false;
的时候 没有假死。而是 可以操作主界面,而且 数据也 同时一点点 显示。同时执行。
难不成 主线程 每隔0.00000秒先执行 1个,然后再执行 另一个,那么来回执行让本人看不出来?那也不对啊!原因是本人操作的时候 没假死。
应该是分配了另一个线程 去执行 一个任务,然后 完成了,再通知,
例如 你 委派 收银员 去买菜,你继续干你的活,买完菜通知你。本人是这么理解的。
CheckForIllegalCrossThreadCalls只是关闭了跨线程调用的检查,假如这个属性本身是不能跨线程赋值的话,可能会出现难以解释的错误
14
2
private void GetData() { //下面两句跑在新建线程 PeelerssPoDetail peerpodtil = new PeelerssPoDetail(); DataTable db = peerpodtil.GetPoDtilList(ParmFilter()); //这句跑在UI线程 dgvData.DataSource = db; //这个过程不能假死 }
那么大致改成这样就行了:
delegate DataTable AsyncGetDataDelegate(); //在线程里处理代码 private DataTable GetData() { PeelerssPoDetail peerpodtil = new PeelerssPoDetail(); return peerpodtil.GetPoDtilList(ParmFilter()); } private void btnAny_Click(object sender, EventArgs e) { AsyncGetDataDelegate d = new AsyncGetDataDelegate(GetData); d.BeginInvoke(ia => dgvData.DataSource = d.EndInvoke(ia), null); }
10
windows 中的程序,本来就是分有 线程安全 和 非线程安全 的版本的。且后者的运行速度要明显高于前者
本人不知道你在开发一个多么复杂的系统,也不知道你已经遇到了什么问题
但是你始终没有提到跨线程访问公共资源时的共享冲突问题
要主界面不假死,就得将耗时工作放到子线程中去
子线程访问主线程元素时,就得将其锁住(lock)
尽管 C# 提供了各种各样的手段,那都只是为了使用起来方便。防止共享冲突的锁,总是要存在的,不管你看见看不见
8