• 多线程-委托的异步


    委托同步方法

    1、Invoke(...)

    delegate string GetName(string name);

    //实例化委托
    GetName getname = new GetName(GetN);

    var invokeName = getname.Invoke("1");
    Console.WriteLine(invokeName);

    2、直接  委托实例名字()

     getname("1");

    委托异步调用
    //异步回调方法,在异步执行完之后执行这个 方法。参数为IAsyncResult  异步执行的返回值  里面包含了异步执行
    AsyncCallback acb = (t) =>
    {
        Console.WriteLine(t.AsyncState);
        Console.WriteLine(t.IsCompleted);
        Console.WriteLine(t.CompletedSynchronously);
    };
    //BeginInvoke前面的参数,是委托的参数,     倒数第二个参数是回调方法 AsyncCallback参数IAsyncResult(注意:IAsyncResult会变成BeginInvoke的返回值),  最后一个参数会赋值给AsyncCallback的参数IAsyncResult里面的状态值
    var stat = getname.BeginInvoke("1", acb, "状态值");
    Console.WriteLine(stat.IsCompleted+"    "+stat.AsyncState);
    //EndInvoke得参数为BeginInvoke的返回值。   EndInvoke会阻塞主线程    一直等到异步结束之后才主线程才往下走
    var endValut = getname.EndInvoke(stat);
    Console.WriteLine(endValut);
    Console.ReadKey();
    View Code

     主要就是

    BeginInvoke(参数列表...(根据委托参数列表),回调参数(异步执行完之后执行的方法),状态值(会设置到BeginInvoke返回值里面的状态字段)),该方法返回IAsyncResult。

    EndInvoke(BeginInvoke返回的类型IAsyncResult),该方法返回委托添加方法的真正返回值,该方法会阻塞主线程一直到异步执行完。

    AsyncCallback

    public delegate void AsyncCallback(IAsyncResult ar); 

    定义:引用在相应异步操作完成时调用的方法。

    参数:异步操作的结果。

    可以看出他是一个委托,没有返回值,有一个参数。在异步执行完后才出发执行。

    IAsyncResult

    1、 public interface IAsyncResult

    定义:表示异步操作的状态。

    包含属性:

    //
    // 摘要:
    //     表示异步操作的状态。
    [ComVisible(true)]
    public interface IAsyncResult
    {
        //
        // 摘要:
        //     获取用户定义的对象,它限定或包含关于异步操作的信息。
        //
        // 返回结果:
        //     用户定义的对象,它限定或包含关于异步操作的信息。
        object AsyncState { get; }
        //
        // 摘要:
        //     获取用于等待异步操作完成的 System.Threading.WaitHandle。
        //
        // 返回结果:
        //     用于等待异步操作完成的 System.Threading.WaitHandle。
        WaitHandle AsyncWaitHandle { get; }
        //
        // 摘要:
        //     获取一个值,该值指示异步操作是否同步完成。
        //
        // 返回结果:
        //     如果异步操作同步完成,则为 true;否则为 false。
        bool CompletedSynchronously { get; }
        //
        // 摘要:
        //     获取一个值,该值指示异步操作是否已完成。
        //
        // 返回结果:
        //     如果操作完成则为 true,否则为 false。
        bool IsCompleted { get; }
    }
    View Code

     BeginInvoke返回的类型就是这个,还有AsyncCallback的参数也是这个,还有EndInvoke的参数也是这个。

    2、IAsyncResult  的通用模式

        IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 FileStream 类提供了 BeginRead 和 EndRead 方法来从文件异步读取字节,它们是 Read 方法的异步版本

        Begin 方法包含同步方法签名中的任何参数,此外还包含另外两个参数:一个AsyncCallback 委托和一个用户定义的状态对象。委托用来调用回调方法,状态对象是用来向回调方法传递状态信息。该方法返回一个实现 IAsyncResult 接口的对象

        End 方法用于结束异步操作并返回结果,因此包含同步方法签名中的 ref 和 out 参数,返回值类型也与同步方法相同。该方法还包括一个 IAsyncResult 参数,用于获取异步操作是否完成的信息,当然在使用时就必须传入对应的 Begin 方法返回的对象实例

        开始异步操作后如果要阻止应用程序,可以直接调用 End 方法,这会阻止应用程序直到异步操作完成后再继续执行。也可以使用 IAsyncResult 的 AsyncWaitHandle 属性,调用其中的WaitOne等方法来阻塞线程。这两种方法的区别不大,只是前者必须一直等待而后者可以设置等待超时

        如果不阻止应用程序,则可以通过轮循 IAsyncResult 的 IsCompleted 状态来判断操作是否完成,或使用 AsyncCallback 委托来结束异步操作。AsyncCallback 委托包含一个 IAsyncResult 的签名,回调方法内部再调用 End 方法来获取操作执行结果

    委托异步执行顺序

    1、BeginInvoke(...)进入新的线程

    2、线程执行完之后执行回调方法AsyncCallback()

    3、如果有EndInvoke,主线程卡在EndInvoke那里,一直到新的线程执行完(并且回调方法AsyncCallback()也执行完)。

    异步委托等待-WaitHandle

    1、IAsyncResult.IsCompleted(异步委托BeginInvok返回的值。AsyncCallback的参数)

    注意:这种等待不会关注回调函数,回调函数可能在他的前面或者后面执行

    //线程等待
    while (stat.IsCompleted)
    {
        Thread.Sleep(20);
    }
    View Code

    可以再等待的时候执行一些动作,但是可能会损耗事件。待优化。

    2、IAsyncResult.AsyncWaitHandle

    获取用于等待异步操作完成的 System.Threading.WaitHandle。(也就是返回该线程的等待句柄)

    System.Threading.WaitHandle

    定义:封装等待对共享资源的独占访问的操作系统特定的对象。

    WaitOne()

    定义:阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号。

    可以设置等待的毫秒数,也可不设置

    WaitHandle.WaitAll(WaitHandle[] waitHandles,...)

    定义:等待指定数组中的所有元素都收到信号。(等待所有的waitHandle都执行完,就是所有的线程执行完)

    这个是静态方法,第一个参数是表示要等待的waitHandles列表

    WaitHandle.WaitAny(WaitHandle[] waitHandles,...)

    定义:等待指定数组中的任一元素收到信号(也就是有一个执行完就可以了)

    这个是静态方法,第一个参数是表示要等待的waitHandles列表

    WaitHandle.SignalAndWait(WaitHandle toSignal, WaitHandle toWaitOn,....)

    定义:向一个 System.Threading.WaitHandle 发出信号并等待另一个。(就是让一个线程等待另外一个线程)

    这个是静态方法,第一个要发出信号的 System.Threading.WaitHandle。第二个参数是表示要等待的waitHandles列表。

    注:没有委托就没有异步多线程。异步是多线程的基础。

    本文例子下载

  • 相关阅读:
    调用Type.InvokeMember()时出现MissingMethodException
    C#学习之Delegate
    WCF之元数据交换 (Metadata Exchange)
    定义Enum的开始和结束,这样就能循环Enum了
    定制自己的Visual Studio的Debugger Visualizer
    C#中 #if DEBUG 和 Conditional("DEBUG")的区别
    从哪里开始学习Windows 8?(zz)
    Macro 小总结
    WPF应用的图标
    如何把 Visutal studio中的“printonbreakpoint”消息打印在程序的任何地方
  • 原文地址:https://www.cnblogs.com/wudequn/p/7499514.html
Copyright © 2020-2023  润新知