对于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; });

Winform软件,不要在线程里操作UI的更多相关文章

  1. 为什么在非UI线程中操作UI的改变失不安全的

    因为你如果允许在非UI线程更新操作UI的东西,那我再另一个非UI线程也可以更新这个Ui的东西 这样就会有冲突,比如你的线程刚好跑到修改UI这里,我的另一个UI也有可能跑到这里,所以这样导致线程不安全. ...

  2. android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法

    MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...

  3. android UI 操作 不要在子线程中操作UI

    不管是android ,还是 ios ,请不要在子线程中操作UI,有时有些崩溃,从报错上看不出什么原因,就有可能是子线程操作了UI:切记,切记! 请放在主线程例: activity.runOnUiTh ...

  4. Android中进程与线程及如何在子线程中操作UI线程

    1. Android进程 一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程.这个线程也是你的应用与界面工具包(android.widget和android.view ...

  5. iOS子线程操作UI问题检查

    iOS开发中,因为大部分函数都不是线程安全的,所以UI子线程中操作UI是非常危险的事,但是有时候因为开发者经验不足,不知道子线程中不能UI,或者知道但是写代码的时候没注意,或者不知道那些函数操作UI了 ...

  6. Android 操作UI线程的一些方法

    我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...

  7. android 不能在子线程中更新ui的讨论和分析

    问题描写叙述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是仅仅能在主线程中更改 ui.子线程要 ...

  8. 线程中更新ui方法汇总

    一.为何写作此文   你是不是经常看到很多书籍中说:不能在子线程中操作ui,不然会报错.你是不是也遇到了如下的疑惑(见下面的代码): @Override protected void onCreate ...

  9. c#线程间操作UI-Invoke和BeginInvoke

    利用Invoke和或BeginInvoke实现线程间操作UI的简单例子. /* 窗体包含一个button和一个richtextbox控件 * 注:必须在子线程中执行Invoke和或BeginInvok ...

随机推荐

  1. c语言结构体&常指针和常量指针的区别

    结构体: 关系密切但数据类型不尽相同, 常指针和常量指针的区别: char * const cp : 定义一个指向字符的指针常数,即const指针,常指针. const char* p : 定义一个指 ...

  2. cocos2d-x iOS真机下载非根目录文件提示下载失败解决办法

    在使用cocos api的Downloader或者AssetsManager下载文件到真机Document目录时,如果是直接下载到document根目录,是没问题的,如果是下载存放到了某个不存在的子目 ...

  3. C#基础——系统登录功能的实现

    一般的登陆界面,都是利用用户名和密码在数据库的匹配关系,来实现登陆的跳转功能. 首先介绍用户数据表的设计. 其中ID列需要设置好增量标识,随着用户的增加,ID的值递增,避免重复. 然后是C#中对数据库 ...

  4. Play jQuery with Node.js

    Motivation Move the fucking browser interactions out of javascript development cycle, since Chrome i ...

  5. DEDECMS 留言薄模块的使用方法

    一.留言薄的安装 留言薄的安装过程和其他插件一样,首先我们进入后台模块管理列表,点击其对应的“安装”: 以上步骤,我们完成了留言薄插件的安装. 二.留言薄的卸载 留言薄的卸载,同样首先我们要进入模块管 ...

  6. python内建函数

    人太懒了,博客就慢慢添加吧,这个话题还有很多要学的,后面实践了再来添加,现在就当是开个头. print(dir(__builtins__))  #获取内建属性.函数列表     print(help( ...

  7. js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版【转】

    之前在修改IE6下的一个显示bug时,查到过这些,贴这备忘,后面给出了详细说明,以前的版本,没仔细的说明,特希望大家也收藏下.   网页可见区域宽: document.body.clientWidth ...

  8. log4g

    org.apache.log4j.Logger 详解 1. 概述 1.1. 背景 在应用程序中添加日志记录总的来说基于三个目的 :监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工 ...

  9. 全面解析sizeof(上) 分类: C/C++ StudyNotes 2015-06-15 10:18 188人阅读 评论(0) 收藏

    以下代码使用平台是Windows7 64bits+VS2012. sizeof是C/C++中的一个操作符(operator),其作用就是返回一个对象或者类型所占的内存字节数,使用频繁,有必须对齐有个全 ...

  10. 获取公网IP

    private static string GetIP() { string tempip = ""; try { WebRequest wr = WebRequest.Creat ...