Winform软件,不要在线程里操作UI
2024-09-01 06:34:23
对于Winform软件,不要在线程里操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false;
于是,把所有的代码都改成主线程委托调用的方式
private delegate void SetTextHandle(string id, string value); private void ThreadSetText(string id, string value)
{
this.Controls.Find(id, true)[0].Text = value;
}
private void SetText(string id, string value)
{
if (this.InvokeRequired)
{
this.Invoke(new SetTextHandle(ThreadSetText), new object[] { id, value });
}
else
{
ThreadSetText(id, value);
}
}
2
// the canonical form (C# consumer) public delegate void ControlStringConsumer(Control control, string text); // defines a delegate type public void SetText(Control control, string text) {
if (control.InvokeRequired) {
control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text}); // invoking itself
} else {
control.Text=text; // the "functional part", executing only on the main thread
}
}
3
public static class ControlHelpers
{
public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : ISynchronizeInvoke
{
if (control.InvokeRequired)
{
control.Invoke(new Action(() => action(control)), null);
}
else
{
action(control);
}
}
}
Use it like this:
private void UpdateSummary(string text)
{
summary.InvokeIfRequired(s => { s.Text = text });
}
3
theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!"));
4
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired) {
control.Invoke(action);
} else {
action();
}
}
调用:
richEditControl1.InvokeIfRequired(() =>
{
// Do anything you want with the control here
richEditControl1.RtfText = value;
RtfHelpers.AddMissingStyles(richEditControl1);
});
更新为:
public static void InvokeIfRequired(this ISynchronizeInvoke obj,
MethodInvoker action)
{
if (obj.InvokeRequired) {
var args = new object[0];
obj.Invoke(action, args);
} else {
action();
}
}
考虑仍出现异常时:
while (!control.Visible)
{
System.Threading.Thread.Sleep(50);
}
5
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
if(c.InvokeRequired)
{
c.Invoke(new Action(() => action(c)));
}
else
{
action(c);
}
}
变更为:
public static void InvokeIfRequired<T>(this T c, Action<T> action)
where T : Control
调用方法:
object1.InvokeIfRequired(c => { c.Visible = true; });
最新文章
- C#中实现并发的几种方法的性能测试
- Azure Application Gateway (2) 面向公网的Application Gateway
- FFT
- android:inputType参数类型说明
- iOS开发小技巧--设置cell左右有空隙,设置分割线的新思路,重写setFrame:让别人在外界无法修改控件的大小
- chmod命令用法
- WeChat Official Account Admin Platform API Introduction
- ASP.NET Web API 使用记录
- Javascript:splice()方法实现对数组元素的插入、删除、替换及去重
- AE+SceneControl源代码共享
- 策略模式设计模式(Strategy)摘录
- 提高你的Java代码质量吧:不要让类型默默转换
- 迈向angularjs2系列(8):angular cli和angular2种子项目
- java基础学习系列二
- 华为笔记HOSTS,便于访问云端存储
- 【转】权限管理学习 一、ASP.NET Forms身份认证
- 从实例角度分析java的public、protected、private和default访问权限
- 关于GPL协议的理解(开源与商用、免费与收费的理解)
- PaaS服务之路漫谈(三)
- Oracle分页(limit方式的运用)