• 温故知新 C# 异步


    1.用Thread实现异步

        class Program
        {
            
    public delegate void EndAsyncDelegate(string str);

            
    static void Main(string[] args)
            {
                Console.WriteLine(
    "Ready Invoke Async Method!");

                Console.WriteLine(
    "Begin!");

                BeginAsyncInvoke();

                Console.WriteLine(
    "Continue!");

                Console.ReadKey();
            }

            
    static void BeginAsyncInvoke()
            {
                EndAsyncDelegate myDelegate 
    = EndAsyncInvoke;//异步完成后要执行的

                ClassForAsync c1 
    = new ClassForAsync(myDelegate);

                ParameterizedThreadStart myThreadStart 
    = new ParameterizedThreadStart(c1.Class1ThreadMethod);

                Thread myThread 
    = new Thread(myThreadStart);

                myThread.Start(
    "123"); //参数"123"
            }

            
    static void EndAsyncInvoke(string str)
            {
                Console.WriteLine(
    "完成--异步调用!");

                Console.WriteLine(
    "异步执行结果 -- AsyncResultStr:{0}", str);
            }

            
    public class ClassForAsync
            {
                
    private EndAsyncDelegate OnAsyncDelegateEnd;

                
    public ClassForAsync(EndAsyncDelegate myDelegate)
                {
                    
    this.OnAsyncDelegateEnd = myDelegate;
                }

                
    public string AsyncResultStr { getset; }

                
    //开始异步调用
                public void Class1ThreadMethod(object obj)
                {
                    Console.WriteLine(
    "开始--异步调用!");

                    AsyncResultStr 
    = obj.ToString();

                    
    this.OnAsyncDelegateEnd(AsyncResultStr);//触发异步完成调用的方法
                }
            }
        }

    这里,我通过构建Thread对象来进行异步,它的参数是一个代理ParameterizedThreadStart myThreadStart = new ParameterizedThreadStart(c1.Class1ThreadMethod); 这个代理接收一个obj类型的参数。另外,Thread还接收另外一个没有参数的代理ThreadStart,可以用来做你不需要参数的动作。

    当异步做完要执行的动作后,就通过this.OnAsyncDelegateEnd(AsyncResultStr);来调用异步完成后的动作,这个只是思路,耦合度还是挺高的,有很大的修改空间。

     

    2.Delegate的BeginInvoke,EndInvoke

    public delegate string AsyncDelegate(string str);

            
    static void Main(string[] args)
            {
              
                AsyncInvoke();

                Console.ReadKey();
            }

            
    static void AsyncInvoke()
            {
                AsyncDelegate a 
    = AsyncDelegateMethod;

                AsyncCallback callBack
    =new AsyncCallback(AsyncDelegateCallBackMethod);

                Console.WriteLine(
    "Start!(Before Async Invoke)");

                IAsyncResult ar
    = a.BeginInvoke("test123", callBack,a);

                Console.WriteLine(
    "Do something else..");

                Console.WriteLine(
    "Continue(After Async Invoke)");

            }

            
    //异步调用开始方法
            static string AsyncDelegateMethod(string str)
            {
                Console.WriteLine(
    "Begin - Async Invoke!");

                
    return str;
            }

            
    static void AsyncDelegateCallBackMethod(IAsyncResult ar)
            {
                
    //异步调用完成后要做的动作
                AsyncDelegate a = ar.AsyncState as AsyncDelegate;

                
    if (a != null)
                {
                    
    string str = a.EndInvoke(ar);

                    Console.WriteLine(str);
                }

                Console.WriteLine(
    "End -Async Invoke!");
            }

    用a.BeginInvoke("test123", callBack,a);来进行异步调用,其中:

    (1)"test123"是传递给异步调用方法的参数

    (2)callBack 是用于异步调用完成后要调用的方法,它是一个AsyncCallback对象(Delegate类型的)

    (3)a是Object类型,这里我把AsyncDelegate对象传入,这样就可以在static void AsyncDelegateCallBackMethod(IAsyncResult ar)方法中,

    通过AsyncDelegate a = ar.AsyncState as AsyncDelegate;获取到AsyncDelegate对象,然后调用a.EndInvoke(ar)法获取返回值。

    a.EndInvoke(ar)内部会调用ar.IsCompleted来判断异步调用是否完成,类似于下面的代码

    while (!ar.IsCompleted)
    {
    }
    //do something

    也可以用ar.AsyncWaitHandle.WaitOne();

    如果没完成,就阻塞当前线程。

    如果完成了异步调用,就返回指定类型的值或者不返回值(取决于代理的定义:public delegate string AsyncDelegate(string str);)

    也可以不在callBack的方法中调用EndInvoke,直接在主线程中调用EndInvoke,但是这样就会阻塞主线程,直到异步调用完成。

     

    3..NET Framework中一些常用类库也提供了BeginXXX和EndXXX的异步调用

       例如常见的SqlCommandWebRequest、FileStream、WebServcie等等。

     

  • 相关阅读:
    :where()和:is()
    响应式布局(媒体查询+rem)
    v-html的问题及解决办法
    Sticky Footer(粘性页脚)
    css多行文字垂直居中
    BFC
    margin负值的情况
    windows系统设置环境变量
    hash和history原生事件
    腾讯WeTest零售行业质量解决方案
  • 原文地址:https://www.cnblogs.com/_dragon/p/2097516.html
Copyright © 2020-2023  润新知