C# 委托与线程通信

1、C#中的委托机制我简单理解为C++中的函数指针。

用法如下: 

使用委托: 

public delegate string MessageDelegate(string message);


public class M
{
    public string T(string message)
    {
        return message;
    }
}

class Program
{
    static void Main(string[] args)
    {
        MessageDelegate md = new MessageDelegate(new M().T);
        Console.WriteLine("Message: " + md("这是一个消息"));
    }
}

委托的定义很明显,他的返回类型和参数需要和被委托的方法一致,调用的时候,为 :  对象.方法(参数)

这是简单的委托的使用,委托更上面一级是事件,我理解为把委托进行封装,使用一个对象来管理一定数量的委托。

一个事件可以绑定多个委托,通过操作符"+=" 、" -="来增加和删除委托(绑定和解绑)具体语法就不再讲了。

2、关于使用委托来进行线程通信,我不知道我的理解对不对,但是我确实是这么做的,而且达到了预期的效果。

一般程序中线程之间的通信,可以使用全局变量来进行,但是这样得设置全局变量为volatile。

或者可以通过socket来进行通信(具体socket的底层原理,实现代码等,不讲了,我也没怎么了解过。)

还可以通过委托来进行。

在WinForm开发中,进程需要在后台处理数据的时候,前端Form上要实时展示数据,如果写在同一个线程中,会造成界面假死的情况,对用户十分不友好。如果使用Application.doEvents(),会造成程序效率低下,如果循环比较大,或者读取数据库的时候需要执行很久,那么也会带来卡死的问题(就是很难拖动啦,但是不是假死或根本拖动不了)。

这个时候,我们可以在处理业务逻辑代码这一部分开启一个线程,Form窗口一个线程,如果把这两个线程放在同一个上下文中并使用全局变量,我感觉代码会很臃肿,而且不优雅。但是如果在业务逻辑线程中对Form控件进行操作,两个线程是无法进行通信的,会抛异常。

当然,C#提供了一个避免抛异常的解决办法:

Form.CheckForIllegalCrossThreadCalls = false;

这一行代码可以让.net不捕捉线程之间非法访问的异常(设置为true则捕捉,false则不捕捉),但是这种方式不推荐。

 

我们可以通过委托的方式来使业务逻辑线程操作Form线程中的控件。

public void AppendText(string message)
{    
    Action act = delegate() {
        this.richTextBox1.AppendText(message);
    };

    this.BeginInvoke(act);
    // this.Invoke(act);
}

Invoke和BeginInvoke,一个是同步执行委托,一个是异步执行委托。

Action类的作用是封装一个无参数也无返回值的委托类型方法,通过这个委托,即可以实现另外一个线程访问Form线程中的控件。但是这种方法有一个缺点,它执行的时候需要切换上下文,这使得他的资源利用率会比较低。

 

 

你可能感兴趣的:(C# 委托与线程通信)