享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
posts - 219, comments - 2359, trackbacks - 162, articles - 45
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

如果你想为一个线程传入变量你怎么办?

ThreadStart可不支持带参数的方法.所以你无法使用Thread来启动一个带参数的方法..

            ThreadStart myThreadDelegate = new ThreadStart(ThreadMethod);
            
//public delegate void ThreadStart();  u can't pass a Parameter
            Thread myThread = new Thread(myThreadDelegate);
            myThread.Start();  
//myThread.Start(o); Wrong! 


不过在.Net1.0下,你可以通过Delegate的异步调用来实现.现在在.Net2.0下提供了ParameterizedThreadStart 这么一个Delegate.它和ThreadStart 的不同就在于可以拥有一个object类型的参数.也就是说你可以通过它来使用Thread类以启动一个线程并传入参数, 和Java很象了,不错的新功能.

using System;
using System.Threading;
namespace ParameterizedThreadStartTest
{
    
class Program
    
{
        
static void Main(string[] args)
        
{

            ParameterizedThreadStart myParameterizedThreadDelegate 
= new ParameterizedThreadStart(ThreadMethod);
            Thread myThread 
= new Thread(myParameterizedThreadDelegate);
            
object o = "hello";
            myThread.Start(o);

        }


        
private static void ThreadMethod(object o)
        
{
            
string str = o as string;
            Console.WriteLine(str);
        }

    }

}



还有一个新增的类BackgroundWorker,可以用于启动后台线程,并在后台计算结束后及时调用主线程的方法.
一个常见的应用就是在DataGrid中载入数据的时候.因为从数据库中载入DataSet比较耗时, 所以你可以使用
BackgroundWorker来进行载入, 当DataSet构造好后就立即绑定上DataGrid. 其实该功能同样可以通过Delegate的异步调用实现不过BackgroundWorker用起来更方便一些.
//1. Instantiate a BackgroundWorker instance:
BackgroundWorker myDataWorker = new BackgroundWorker(); 

//2. Setup a DoWork delegate that does the work that you want to be done on the background thread.  

myDataWorker.DoWork 
+= new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs) 
                                                
{
                                                    workerEventArgs.Result 
= new XXXDAL().GetData();
                                                }

                                                );

//3. Setup a RunWorkerCompleted delegate that handles updating your UI with the data recieved on the background thread.
myDataWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs workerEventArgs) 
                                                        
{
                                                            DataSet data 
= (DataSet) workerEventArgs.Result;
                                                            
this.dataGrid.DataSource = data;
                                                        }

                                                        );

//4.Run your worker by calling the RunWorkerAsync() method on your BackgroundWorker instance.
myDataWorker.RunWorkerAsync();

顺便关注一下C#3.0
PDC上 Anders Hejlsberg将介绍未来的语言改进方向.
          C#: Future Directions in Language Innovation from Anders Hejlsberg
Join Anders Hejlsberg, Distinguished Engineer and chief architect of the C# language, for an in-depth walkthrough of the new language features in C# 3.0. Understand how features like extension methods, lambda expressions, type inference, and anonymous types make it possible to create powerful APIs for expressing queries and interacting with objects, XML, and databases in a strongly typed, natural way.
Session Level(s): 300
Track(s): Tools & Languages

以后需要关注以下方面(很多方面和动态语言相关,推荐大家学习一下Python Ruby,谁有什么好的指导?):
  1. Extension methods
  2. Lambda expressions
  3. Type inference and implicit types
  4. Anonymous types
  5. Expression Trees
有谁有经验的来介绍一下.
0
0
(请您对文章做出评价)
« 上一篇:Guidance about Design
» 下一篇:A simple way to roll back DB pollution in Test

Feedback

#1楼   回复  引用  查看    

2005-07-25 22:59 by lion      
在.Net1.0中直接通过ThreadPool.QueueUserWorkItem方法也可以实现在线程中传入参数

#2楼   回复  引用  查看    

2005-07-25 23:55 by Bruce      
ThreadPool.QueueUserWorkItem是使用线程池,和线程有点区别。
1.0里也可调用参数,就是比较麻烦

public class C1
{
private object _arg;
public C1(object arg)
{
_arg = arg;
}

public void Start()
{
//some code
}
}

C1 c1;
c1 = new C1("arg");
new Thread(new ThreadStart(c1.Start)).Start();

#3楼   回复  引用  查看    

2005-07-26 09:44 by Ninputer      
VB9.0已经确定要加入C omega的关系型数据操作语法(类似SQL),同时VB组也在积极思考从动态语言吸取优势,我期望他们能对字符串操作有一次大的改进。

#4楼   回复  引用    

2005-07-26 17:35 by today[未注册用户]
我觉得如果需要传两个以上的参数,我们应该怎么办呢?我们还不是需要封装一些结构或者类来实现嘛,(把参数object替换掉,还得装箱,拆箱)感觉还是不怎么好用,当然比以前好用多了,我在想为什么他们不把参数设置为object[]数组呢?这样的话,感觉上比较好用。
小弟愚昧,还请各位赐教!

#5楼   回复  引用    

2005-07-26 20:08 by idior[未注册用户]
一般来说不需要为线程传入很多的参数.
如果是多个参数可以用一个类(不要用结构)来实现.
不存在你说的装箱,拆箱操作. 那个是值对象才有. 倒是需要cast操作, 不想cast只能通过generic.不过现在似乎没提供这个功能.

#6楼   回复  引用  查看    

2005-07-27 09:32 by today      
在net 1.0时我们要传参数的话,就需要封装成类,也就是Bruce所说的那样,在2.0里他多了个带参数的线程,参数的类型为object,如果我需要传一个int值,难道你不认为这存在装箱和拆箱的动作嘛?还有就是如果我想传递两个参数,这两个参数只是两个参数(我只想把他们传给委托方法,其他的我什么也不想做),你说我还有必要把它封装成类嘛,封装成结构,然后作为一个参数不就得了嘛,其实我实在不敢和你争论,我只是觉得奇怪,为什么不把参数设置为object[]数组呢?这样你就可以传两个以上的参数而不必再封装成一个结构了。

#7楼   回复  引用    

2005-07-27 13:48 by idior[未注册用户]
不是争论,而是讨论。
如果是int(value type),那是存在box操作。
如果是两个int 那用一个类包装起来就好了啊。 用struct(value type)就会有box,unbox了。

一般来说不需要为线程传入很多的参数,基本上用一个object就可以满足应用了。可能微软觉得没必要用object []吧。

#8楼   回复  引用    

2006-02-17 16:06 by wedde[未注册用户]
object[]也是object的一种,直接传递就可以了

#9楼   回复  引用  查看    

2006-04-17 10:41 by 九头龙      
BackgroundWorker,这个东东真的是不好用,有Bug,我的一个程序用了它,一天内收发数据一点问题也没有,大约25个小时以后,突然出了错说不在创建XXX控件的线程访问它,真是莫名其妙,我是在ProgressChanged事件函数里访问的某个UI控件,同样的代码防问了一天都没问题,怎么突然会出错了。这个东东很不稳定,有是线程是错的。不信你可以用System.IO.Port里的seriarport类和它一起用来收串口数据,怎么做都会出现"不在创建XXX控件的线程访问它"这条错误

#10楼   回复  引用    

2007-06-15 10:26 by Frank[未注册用户]
有谁知道,BackgroudWorker这个东东和以前的delegate+callback机制有什么本质的区别吗?还是说这其实是一回事?

#11楼   回复  引用    

2007-07-24 16:14 by 思考中的程序员[未注册用户]
2006-02-17 16:06 by wedde
object[]也是object的一种,直接传递就可以了

没错
把一个object[] 赋给object就可以了

#12楼   回复  引用    

2009-03-31 13:28 by 同城二手书网[未注册用户]
好好 !

同城二手书网
http://www.2shoushu.com/