.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; } } }