笔者最近在做项目的时候,遇到一个这样的问题:厂商提供的SDK,里面的某些资源必须要在子线程中创建,并且相应资源中的操作也必须在相应的线程中调用。类似与Winform中更新控件必须要将相应的操作委托给拥有控件的线程去处理,Control类中的Invoke以及BeginInvoke方法。本人愚钝,没有想到好的方法,用了一个比较简单的实现方式。
废话少说,直接上代码:
1 class ThreadObject 2 { 3 private AutoResetEvent startEvent = new AutoResetEvent(false); 4 private AutoResetEvent endEvent = new AutoResetEvent(false); 5 bool isRuning = false; 6 7 /// <summary> 8 /// 需要执行的方法 9 /// </summary> 10 Delegate _method ; 11 12 /// <summary> 13 /// 方法参数 14 /// </summary> 15 object[] _args; 16 17 /// <summary> 18 /// 目标实例,如果需要委托的非静态方法,则需要将方法所在的实例传过来 19 /// </summary> 20 object _targetObject; 21 22 /// <summary> 23 /// 方法返回值 24 /// </summary> 25 object returnValue; 26 27 public ThreadObject() 28 { 29 isRuning = true; 30 Thread thread = new Thread(new ThreadStart(Working)); 31 thread.Start(); 32 } 33 34 public object TargetObject 35 { 36 get {return _targetObject; } 37 set { _targetObject = value; } 38 } 39 40 private void Working() 41 { 42 while (isRuning) 43 { 44 startEvent.WaitOne(); 45 if (_method != null) 46 { 47 var me = _method.Method; 48 returnValue = me.Invoke(TargetObject, _args); 49 endEvent.Set(); 50 } 51 } 52 53 } 54 55 public void Stop() 56 { 57 isRuning = false; 58 startEvent.Set(); 59 } 60 61 /// <summary> 62 /// 在Start ()创建的线程中执行方法 63 /// </summary> 64 /// <param name="method"></param> 65 /// <param name="args"></param> 66 /// <returns></returns> 67 public object InvokeCall(Delegate method, params object[] args) 68 { 69 this._method = method; 70 this._args = args; 71 startEvent.Set(); 72 endEvent.WaitOne(); 73 method = null; 74 return returnValue; 75 } 76 }
实现的比较简单,里面注释应该说的很清楚。
其实里面还有一些问题:1、只有同步方法,没有异步方法。2、线程同步需要完善。
调用方法:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("Main Thread ID:{0}\n", Thread.CurrentThread.ManagedThreadId); 6 Console.WriteLine("\n在主线程中调用方法===================》"); 7 DoSomeThing(); 8 var ret = DoSomeThingWithArgs(13, 26); 9 Console.WriteLine("返回值为{0}", ret); 10 11 Console.WriteLine("\n委托给其他线程调用===================》"); 12 13 ThreadObject mo = new ThreadObject(); 14 Thread.Sleep(3000); 15 var o = mo.InvokeCall(new Action(DoSomeThing)); 16 Console.WriteLine(o); 17 18 ret = (int)mo.InvokeCall(new Func<int, int, int>(DoSomeThingWithArgs), new object[] { 13, 26 }); 19 Console.WriteLine(ret); 20 Console.ReadKey(); 21 22 } 23 static int DoSomeThingWithArgs(int i, int j) 24 { 25 Console.WriteLine("TestParams Method In Thread ID:{0}", Thread.CurrentThread.ManagedThreadId); 26 return i + j; 27 } 28 static void DoSomeThing() 29 { 30 Console.WriteLine("DoSomeThing Method In Thread ID:{0}", Thread.CurrentThread.ManagedThreadId); 31 32 Console.WriteLine("DoSomeThing"); 33 } 34 35 }
运行效果:
对于将相应的方法委托给相应的线程执行,我相信有更好的实现方式,如果有了解的朋友,希望能够告知。
时间: 2024-10-24 20:03:37