• C# 多线程操作之异步委托


     

    标签: 多线程任务nullstringhtml工作
     分类:
     
     

    目录(?)[+]

     

    在应届生找工作的时候,多线程操作几乎是所有的公司都会问及的一个基本问题。

    这里做了一个多线程操作的总结,这里总结了通过异步委托来实现多线程操作。

    定义一个委托,是创建一个线程的最简单的方法,并且异步调用它。委托是方法的类型安全的引用。同时委托还智齿异步调用方法。

    委托使用线程池来完成异步任务。

    当自己的程序使用异步委托的时候,委托会自动创建ige执行线程的任务。委托使用线程池完成异步任务,所有的异步委托调用,都会通过调用系统线程池中的线程来完成调用异步任务。

    在下面的简单例子中,我们定义了一个异步委托,并在每次输出的时候显示该函数运行在哪个线程中。

    在异步委托中,可以使用三种技术来异步的调用委托。下面分别介绍三种调用异步委托的方法。

    1. 投票判断异步委托是否完成

    在委托中调用BeginInvoke()方法,返回IAsyncResult结果。程序的源代码如下:

    [csharp] view plaincopy
     
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Threading;  
    6.   
    7. namespace AsyncDelegate  
    8. {  
    9.     class Program  
    10.     {  
    11.         public delegate int TakeSomeTimeDelegate(int data,int ms);  
    12.   
    13.         static void Main(string[] args)  
    14.         {  
    15.             TakeSomeTimeDelegate dl=TakeSomeTime;  
    16.             IAsyncResult ar=dl.BeginInvoke(1,200,null,null);  
    17.   
    18.             while (!ar.IsCompleted)  
    19.             {  
    20.                 Console.WriteLine(".");  
    21.                 Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);  
    22.                 Thread.Sleep(50);  
    23.             }  
    24.   
    25.             int result = dl.EndInvoke(ar);  
    26.             Console.WriteLine("Result:{0}", result);  
    27.         }  
    28.   
    29.         static int TakeSomeTime(int data, int ms)  
    30.         {  
    31.             Console.WriteLine("TakeSomeTime started!");  
    32.             Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);  
    33.             Thread.Sleep(ms);  
    34.             Console.WriteLine("TakeSomeTime Completed!");  
    35.             return ++data;  
    36.         }  
    37.     }  
    38. }  


     

    该程序的输出结果如图:

    可以看到主线程和异步委托线程是同时执行的。

    如果在委托结束之前不等待委托完成其他任务就结束主线程,委托线程就会停止。

    int result = dl.EndInvoke(ar); 这里的EndInvoke()函数会一直等在异步委托完成并在异步委托完成之前阻断主线程。这样就可以通过这个函数保证异步委托能够正确完成。

     

    2. 等待句柄判断异步委托完成

    通过AsyncWatiHandle属性,访问等待句柄。WaitOne()方法阻断当前线程,直到异步调用线程完成返回可以利用的句柄以后再执行当前线程。

    程序:

    [html] view plaincopy
     
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Threading;  
    6.   
    7. namespace AsyncDelegate  
    8. {  
    9.     class Program  
    10.     {  
    11.         public delegate int TakeSomeTimeDelegate(int data,int ms);  
    12.   
    13.         static void Main(string[] args)  
    14.         {  
    15.             TakeSomeTimeDelegate dl=TakeSomeTime;  
    16.             IAsyncResult ar=dl.BeginInvoke(1,200,null,null);  
    17.   
    18.             while (true)  
    19.             {  
    20.                 Console.WriteLine(".");  
    21.                 Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);  
    22.                 if (ar.AsyncWaitHandle.WaitOne(100, false))  
    23.                 {  
    24.                     Console.WriteLine("Can get the result now");  
    25.                     break;  
    26.                 }  
    27.             }  
    28.   
    29.             //while (!ar.IsCompleted)  
    30.             //{  
    31.             //    Console.WriteLine(".");  
    32.             //    Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);  
    33.             //    Thread.Sleep(50);  
    34.             //}  
    35.   
    36.             int result = dl.EndInvoke(ar);  
    37.             Console.WriteLine("Result:{0}", result);  
    38.         }  
    39.   
    40.         static int TakeSomeTime(int data, int ms)  
    41.         {  
    42.             Console.WriteLine("TakeSomeTime started!");  
    43.             Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);  
    44.             Thread.Sleep(ms);  
    45.             Console.WriteLine("TakeSomeTime Completed!");  
    46.             return ++data;  
    47.         }  
    48.     }  
    49. }  


    运行结果:

    ar.AsyncWaitHandle.WaitOne()阻断了当前线程, 直到异步调用线程完成获得可以利用的句柄以后再次执行当前线程。

     

    3. 利用异步回调函数判断异步调用线程是否结束

    回调函数的操作比较复杂, 而且对于程序的理解和维护造成非常大的困难。所以一般情况下能不用回调函数就不要使用回调函数。

    使用回调函数,必须注意这个函数从委托线程中调用,而不是从主线程中调用回调函数。

    [csharp] view plaincopy
     
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Threading;  
    6.   
    7. namespace AsyncDelegate  
    8. {  
    9.     class Program  
    10.     {  
    11.         public delegate int TakeSomeTimeDelegate(int data,int ms);  
    12.   
    13.         static void Main(string[] args)  
    14.         {  
    15.             TakeSomeTimeDelegate dl=TakeSomeTime;  
    16.             IAsyncResult ar = dl.BeginInvoke(1, 200, TakeSomeTimeCompleted, dl);  
    17.             for (int i = 0; i < 10;i++ )  
    18.             {  
    19.                 Console.WriteLine(".");  
    20.                 Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);  
    21.                 Thread.Sleep(50);  
    22.             }  
    23.   
    24.             //int result = dl.EndInvoke(ar);  
    25.             //Console.WriteLine("Result:{0}", result);  
    26.         }  
    27.   
    28.         static int TakeSomeTime(int data, int ms)  
    29.         {  
    30.             Console.WriteLine("TakeSomeTime started!");  
    31.             Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);  
    32.             Thread.Sleep(ms);  
    33.             Console.WriteLine("TakeSomeTime Completed!");  
    34.             return ++data;  
    35.         }  
    36.   
    37.         static void TakeSomeTimeCompleted(IAsyncResult ar)  
    38.         {  
    39.             if (ar==null)  
    40.             {  
    41.                 throw new ArgumentNullException("ar");  
    42.             }  
    43.             TakeSomeTimeDelegate dl = ar.AsyncState as TakeSomeTimeDelegate;  
    44.             int result = dl.EndInvoke(ar);  
    45.             Console.WriteLine("result : {0}", result);  
    46.             //Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);  
    47.         }  
    48.     }  
    49. }  


     

    运行结果:

     
     
  • 相关阅读:
    NYOJ-括号配对问题--------待解决,RE
    NYOJ-小猴子下落
    UVA401
    UVA11059
    生成1-N的排列
    C++ STL, next_permutation用法。
    C++ STL, set用法。 待更新zzzzz
    C++ STL, sort用法。
    C++中getline的用法
    TCP系列34—窗口管理&流控—8、缓存自动调整
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/5469267.html
Copyright © 2020-2023  润新知