.net 非阻塞事件获取返回异步回调结果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace AsyncCallBack_Delegate
{
    class Program
    {
        static void Main(string[] args)
        {
            JobManager manager = new JobManager();
            ReadJob read = manager.Run<ReadJob>();
            read.Started += new EventHandler(read_Started);
            read.Completed += new EventHandler<CompletedEventArgs>(read_Completed);
            read.OnUnhandledException += new EventHandler<ExceptionEventArgs>(read_OnUnhandledException);
            read.Execute();

            while (!read.IsCompleted)
            {
                Console.WriteLine("Main thread[" + Thread.CurrentThread.ManagedThreadId + "] is waiting to close...");
                Thread.Sleep(500);
            }

            Console.WriteLine("ReadJob is completed and return value: " + read.RetVal);

            Console.WriteLine("Jobs have been finished, press any key to continue...");
            Console.ReadKey();

        }

        static void read_OnUnhandledException(object sender, ExceptionEventArgs e)
        {
            Console.WriteLine("Exception:" + sender.GetType().FullName + " Exception message:" + e.Message);
        }

        static void read_Completed(object sender, CompletedEventArgs e)
        {
            Console.WriteLine("Completed:" + sender.GetType().FullName + " Process executed result:" + e.Success);
        }

        static void read_Started(object sender, EventArgs e)
        {
            Console.WriteLine("Started:" + sender.GetType().FullName);
        }
    }

    public class JobManager
    {
        public T Run<T>() where T : IJobService, new()
        {
            return new T();
        }
    }

    public interface IJobService
    {
        void Execute();
        event EventHandler<CompletedEventArgs> Completed;
        event EventHandler Started;
        event EventHandler<ExceptionEventArgs> OnUnhandledException;

    }

    delegate void ProcessDelegate(string message);

    public class ReadJob : IJobService
    {
        //定义供ReadJob实例对象对外注册的事件
        public event EventHandler Started;
        public event EventHandler<CompletedEventArgs> Completed;
        public event EventHandler<ExceptionEventArgs> OnUnhandledException;

        object lockObj = new object();

        event EventHandler<CompletedEventArgs> IJobService.Completed
        {
            add
            {
                lock (lockObj)
                {
                    Completed += value;
                }
            }
            remove
            {
                lock (lockObj)
                {
                    Completed -= value;
                }
            }
        }
        event EventHandler IJobService.Started
        {
            add
            {
                lock (lockObj)
                {
                    Started += value;
                }
            }
            remove
            {
                lock (lockObj)
                {
                    Started -= value;
                }
            }
        }
        event EventHandler<ExceptionEventArgs> IJobService.OnUnhandledException
        {
            add
            {
                lock (lockObj)
                {
                    OnUnhandledException += value;
                }
            }
            remove
            {
                lock (lockObj)
                {
                    OnUnhandledException -= value;
                }
            }
        }

        public bool IsCompleted { get; set; }
        public bool RetVal { get; set; }

        public void Execute()
        {
            IsCompleted = false;
            RetVal = false;

            EventHandler eventHandler = Started;
            if (null != eventHandler)
            {
                eventHandler(this, new EventArgs());
            }

            //异步回调方式调用Process方法
            //返回值和Completed事件在回调方法中调用
            ProcessDelegate process = Process;
            process.BeginInvoke("ReadJob", CompletedMethod, process);

        }

        public void Process(String message)
        {
            Console.WriteLine("Process thread[" + Thread.CurrentThread.ManagedThreadId + "]:" + message + " JobService:" + this.GetType().FullName);
            Thread.Sleep(2000);

            //test
            //throw new Exception("test exception");

        }

        //异步回调执行完毕后调用的方法
        public void CompletedMethod(IAsyncResult result)
        { 
            //获取返回值
            try
            {
                (result.AsyncState as ProcessDelegate).EndInvoke(result);
                RetVal = true;

                //线程同步 使用临时变量代替eventhandler,委托是不可变的immutable
                //也可以使用 Interlocked.CompareExchange(ref eventhandler,null,null)
                EventHandler<CompletedEventArgs>  eventHandler = Completed;
                if (null != eventHandler)
                {
                    eventHandler(this, new CompletedEventArgs(true));
                }
            }
            catch (Exception ex)
            {
                //异常处理的事件再次执行,线程同步 使用临时变量代替eventhandler,委托是不可变的immutable
                //也可以使用 Interlocked.CompareExchange(ref eventhandler,null,null)
                EventHandler<ExceptionEventArgs> eh = OnUnhandledException;
                if (null != eh)
                {
                    eh(this, new ExceptionEventArgs(ex.Message));
                }
                RetVal = false;
            }
            //执行Completed事件注册的方法,此处使用eventHandler临时变量避免在判断是否为null时事件被移除
            //若多线程需要使用
            IsCompleted = true;
        }

    }

    public class CompletedEventArgs : EventArgs
    {
        public bool Success { get; set; }
        public CompletedEventArgs(bool success)
        {
            this.Success = success;
        }
    }

    public class ExceptionEventArgs : EventArgs
    {
        public string Message { get; set; }
        public ExceptionEventArgs(string message)
        {
            this.Message = message;
        }
    }


}

 

posted @ 2016-04-12 15:31  尹庆超  阅读(702)  评论(0编辑  收藏  举报