在子线程实现自己的Invoke方法

笔者最近在做项目的时候,遇到一个这样的问题:厂商提供的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

在子线程实现自己的Invoke方法的相关文章

Android子线程更新UI主线程方法之Handler

背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. 下面说下有关Handler相关的知识. 多线程一些基础知识回顾:在介绍Handler类相关知识之前,我们先看看在Java中是如何创建多线程的方法有两种:通过继承Thread类,重写Run方法来实现通过继承接口Runnable实现多线程 具体两者的区别与实现,看看这篇文章中的介绍:http://de

android子线程中更新UI的方法

在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 参考:Android子线程 方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: //

子线程更新主线程的方法-转

Android的UI更新只能在UI线程中,即主线程.子线程中如果要进行UI更新,都是要通知主线程来进行. 几种实现方式总结如下,欢迎补充. 1.runOnUiThread() 子线程中持有当前Activity引用(假如为Activity mActivity;),即可以调用mActivity的runOnUiThread(Runnable r)方法. 2.post()和postDelay() 子线程如果持有某个View的引用,要对该View进行更新,则可调用该View对象的post(Runnable

业务代码中(java class)中如何实现多线程,并且将子线程中的值随方法返回返回值

转载自http://bbs.csdn.net/topics/390731832 问题: public static String getAddress(final InputStream inputStream, final String mobile) { new Thread() { public void run() { try { Log.i(TAG, "inputStream: " + inputStream.available()); String soap = readS

主线程和子线程的区别

每个线程都有一个唯一标示符,来区分线程中的主次关系的说法. 线程唯一标示符:Thread.CurrentThread.ManagedThreadID; UI界面和Main函数均为主线程. 被Thread包含的"方法体"或者"委托"均为子线程. 委托可以包含多个方法体,利用this.Invoke去执行. 也可以定义多种方法体,放在Thread里面去执行.则此方法体均为子线程.注意如果要修改UI界面的显示.则需要使用this.Invoke,否则会报异常. Main函数为

关于Activity销毁,而绘制UI的子线程未销毁出现的问题

最近做一个项目,有一个功能模块,需要播放音频,画一个简单的界面 一个例子: 我们都知道播放音频要用到MediaPlayer类,我这里,不需要开启Service,就在本Activity播放音频,当Activity销毁的时候,音频便结束 但是有一个重点,需要即时的变化当前播放的时间 我的思路是,开启一个线程,计算当前音频的剩余播放时间,如果>0 则用Handler循环发送一个消息来更改时间UI Thread tPlay ; tPlay = new Thread(new Runnable() { @O

IOS 线程处理 子线程

IOS 线程处理 子线程的启动与结束 技术交流新QQ群:414971585 IOS中,如果要在主线程中启动一个子线程,可以又两种方法: [NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil]; 这是在cocoa早期提供的方法,因此你可以在任何版本的ios和mac上调用此方法.在 OS X v10.5(or later)和IOS中,苹果又提供了一种方法,可以允许你获

C#学习之在辅助线程中修改UI控件----invoke方法

Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dotnet程序员众所周知的,我在此费点笔墨再次记录到自己

C#子线程更新UI控件的方法总结

http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从子线程直接修改控件属性时会出现“从不是创建控件的线程访问它”的异常提示. 跨线程更新UI控件的常用方法有两种: 1.使用控件自身的invoke/BeginInvoke方法 2.使用SynchronizationContext的Post/Send方法更新 1.使用控件自身的invoke/BeginIn