在线程池中调用委托

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        /// <summary>
        /// 定义一个委托
        /// </summary>
        private delegate string RunOnThreadPool(out int threadId);

        private static string TestMethod(out int threadId)
        {
            Console.WriteLine("TestMethod开始..... " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Thread.Sleep(TimeSpan.FromSeconds(2));

            CurrentThreadInfo("TestMethod()的");


            threadId = Thread.CurrentThread.ManagedThreadId;

            string result = String.Format("TestMethod返回线程Id:{0}", threadId.ToString());
            return result;
        }

        private static void CallbackMethod(IAsyncResult asyncResult)
        {
            Console.WriteLine("CallbackMethod开始..... " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Console.WriteLine("IAsyncResult的状态:" + asyncResult.AsyncState);


            CurrentThreadInfo("Callback()的");
        }

/// <summary> /// 在线程池中调用委托 /// </summary> static void Main() { CurrentThreadInfo("主线程Main()的"); int threadId = 0;
var t1 = new Thread(() => { Console.WriteLine("t1开始....." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); TestMethod(out threadId); }); t1.Start(); t1.Join(); Console.WriteLine("当前threadId:" + threadId.ToString()); Console.WriteLine("RunOnThreadPool委托开始....." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); RunOnThreadPool dele = TestMethod; IAsyncResult asyncResult = dele.BeginInvoke(out threadId, CallbackMethod, "一个异步委托调用"); asyncResult.AsyncWaitHandle.WaitOne(); string result = dele.EndInvoke(out threadId, asyncResult); Console.WriteLine("最后打印结果:【{0}】 -- 【{1}】", threadId, result); Console.WriteLine("当前主线程线程Id:" + Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine("执行完成"); Console.ReadLine(); } /// <summary> /// 当前线程信息 /// </summary> private static void CurrentThreadInfo(string name) { StringBuilder builder = new StringBuilder(); builder.AppendLine(""); builder.AppendLine(String.Format("{0}线程Id:\t\t{1}", name, Thread.CurrentThread.ManagedThreadId)); builder.AppendLine(String.Format("{0}是否使用线程池:\t{1}", name, Thread.CurrentThread.IsThreadPoolThread)); builder.AppendLine(String.Format("{0}是否后台线程:\t{1}", name, Thread.CurrentThread.IsBackground)); builder.AppendLine(String.Format("{0}线程状态:\t\t{1}", name, Thread.CurrentThread.ThreadState.ToString())); builder.AppendLine(String.Format("{0}当前时间:\t\t{1}", name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); builder.AppendLine(""); Console.WriteLine(builder.ToString()); } } }

 

打印结果:

/*
 
主线程Main()的线程Id:           9
主线程Main()的是否使用线程池:    False
主线程Main()的是否后台线程:      False
主线程Main()的线程状态:         Running
主线程Main()的当前时间:         2016-08-15 14:46:43


t1开始.....2016-08-15 14:46:43
TestMethod开始..... 2016-08-15 14:46:43

TestMethod()的线程Id:           10
TestMethod()的是否使用线程池:    False
TestMethod()的是否后台线程:      False
TestMethod()的线程状态:         Running
TestMethod()的当前时间:         2016-08-15 14:46:45


当前threadId:10
RunOnThreadPool委托开始.....2016-08-15 14:46:45
TestMethod开始..... 2016-08-15 14:46:45

TestMethod()的线程Id:           11
TestMethod()的是否使用线程池:    True
TestMethod()的是否后台线程:      True
TestMethod()的线程状态:         Background
TestMethod()的当前时间:         2016-08-15 14:46:47


CallbackMethod开始..... 2016-08-15 14:46:47
最后打印结果:【11】 -- 【TestMethod返回线程Id:11】
当前主线程线程Id:9
执行完成
IAsyncResult的状态:一个异步委托调用

Callback()的线程Id:             11
Callback()的是否使用线程池:      True
Callback()的是否后台线程:        True
Callback()的线程状态:           Background
Callback()的当前时间:           2016-08-15 14:46:47

 */

 

 

工作原理:

定义一个委托( private delegate string RunOnThreadPool(out int threadId); ) 并调用BeginInvoke()方法来运行该委托。

BeginInvoke()方法接受一个回调函数。

该回调函数会在异步操作完成后会被调用,并且一个一个用户自定义的状态会传给该回调函数。

结果,我们得到了一个实现了IAsyncResult接口的asyncResult对象。

BeginInvoke()方法立即返回了结果,当线程池中的工作线程在执行异步操作时,仍允许我们继续其他工作。

当需要异步操作的结果时,可以使用BeginInvoke()方法调用返回的asyncResult对象。

例子中使用AsyncWaitHandle属性来等待,直到操作完成。

当操作完成后,会得到一个结果,可以通过委托调用EndInvoke()方法将IAsyncResult对象传递为委托参数。

 

注意:

当操作完成后,传递给BeginInvoke()方法的回调函数将被放置在线程池中。

确切地说是在一个工作线程中。

posted @ 2016-08-15 13:17  茗::流  阅读(286)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。