跨线程的安全更新控件

在你的工程中的扩展方法类中写下一个SafeCall方法:
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public static class Extensions
    {
        public static void SafeCall(this Control ctrl, Action callback)
        {
            if (ctrl.InvokeRequired)
                ctrl.Invoke(callback);
            else
                callback();
        }
    }
}
它只是把你要保护起来的代码作为一个回调而已。然后任何需要保护一些代码的地方都可以这样调用:
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(h =>
            {
                for (var i = 0; i < 10000000; i++)
                {
                    label1.SafeCall(() =>
                    {
                        label1.Text = i.ToString();
                    });
                    Thread.Sleep(100);
                }
            });
        }

    }
}
当然,使用lamda是我的一个“坏毛病”。其实这里完全可以使用传统的匿名委托写法:

using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(h =>
            {
                for (var i = 0; i < 10000000; i++)
                {
                    label1.SafeCall(delegate()
                    {
                        label1.Text = i.ToString();
                    });
                    Thread.Sleep(100);
                }
            });
        }

    }
}

 

时间: 2024-09-29 10:57:16

跨线程的安全更新控件的相关文章

跨线程调用窗体控件

本文转载:http://www.csharpwin.com/csharpspace/11279r6763.shtml   执行耗时较长的操作时,使用多线程是明智之举,它可以提高程序 UI 的响应速度,使得一切运行显得更为快速.在 Windows 中进行多线程编程曾经是 C++ 开发人员的专属特权,但是现在,可以使用所有兼容 Microsoft .NET 的语言来编写. 不过Windows 窗体体系结构对线程使用制定了严格的规则.如果只是编写单线程应用程序,则没必要知道这些规则,这是因为单线程的代

Android线程中设置控件的值提示报错的解决方法_Android

本文实例讲述了Android线程中设置控件的值提示报错的解决方法.分享给大家供大家参考,具体如下: 在Android线程中设置控件的值一般会与Handler联合使用,如下: package com.yarin.android.Examples_04_15; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import andro

线程与mscomm控件问题

问题描述 线程与mscomm控件问题 我是在做下位机向上位机传递数据,使用的mfc基于对话框的mscomm控件.需要动态实时显示曲线.我采用teechart控件来画曲线.mscomm控件有个Onmscomm()函数用来接收串口通信数据并存储起来.现在开辟了一个线程,在线程函数里实现对Onmscomm()接收到的数据的处理(此处为while(true)循环),再将处理的数据用来画图.但是现在调试时程序进入开辟的线程函数里,始终跳不出,无法进入Onmscomm()函数里(下位机有传数据),运行时会显

c# 子线程调用timer控件 我打了断点发现没执行;要怎么才能让他执行呢

问题描述 c# 子线程调用timer控件 我打了断点发现没执行:要怎么才能让他执行呢 c# 子线程调用timer控件 我打了断点发现没执行:要怎么才能让他执行呢 解决方案 不要直接调用UI组件,Thread自己有Timer,定时执行后,通过委托去控制UI

C# 多线程动态创建控件并访问由该线程创建的控件

问题描述 RT我在一个线程里面操作文件,有几个文件就创建几个线程.我想在UI上动态的创建几个进度条控件.怎么做?想了半天想不到啥...窝是菜鸟!求各路大神指点一二 解决方案 解决方案二:所有控件都只能有主线程创建,如果使用后台线程创建,时不时会有异常跳出.解决方案三:我用主线程创建,然后根据一定的规律来命名这些控件,然后在另外一个线程里面把处理好的数据和要使用的控件名用委托传回来,然后再在主线程里面找到这个控件并把数据添加到控件里面你觉得这样可以嘛?解决方案四:引用1楼CGabriel的回复:

C# 后台线程更新UI控件

/********************************************************************************* * C# 后台线程更新UI控件 * 说明: * C#多线程更新UI控件的方法,每次都要找,记录一下,方便检索. * * 2017-10-23 深圳 南山平山村 曾剑锋 ********************************************************************************/ 一

Android线程中设置控件的值提示报错的解决方法

本文实例讲述了Android线程中设置控件的值提示报错的解决方法.分享给大家供大家参考,具体如下: 在Android线程中设置控件的值一般会与Handler联合使用,如下: package com.yarin.android.Examples_04_15; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import andro

C#串口收发数据,子线程更新textbox控件内容,一段时间后,界面卡死,请教问题原因所在

问题描述 1.现象描述:我自己用C#做了一个模拟流量计软件,下位机大概每100ms会发送一些数据(8字节),我的软件接收后,响应一个9字节的数据.数据的接收和发送都在richtextbox中显示出来.我开了一个子线程,这个线程每100ms去更新textbox控件内容,(就是先读取textbox的内容,在此基础上递增一个常量,再显示在textbox中),程序能够正常运行一段时间,然后就出现了界面卡死的现象,串口能够正常收发,richtextbox中的日志数据能够正常打印,但就是主界面死掉了,点什么

VC2010 Unicode字符集下通过ReadProcessMemory跨进程读取SysListView32控件总是乱码

问题描述 //----------------------------------------------------------------------------------//将宽字节wchar_t*转换单字节char*inlinechar*UnicodeToAnsi(constwchar_t*szStr){intnLen=WideCharToMultiByte(CP_ACP,0,szStr,-1,NULL,0,NULL,NULL);if(nLen==0){returnNULL;}char