查看MSDN看到Thread类有4个构造函数 有两个主要参数:ThreadStart和ParameterizedThreadStart;
查看MSDN可以看出:
1、ThreadStart是一个无参没有返回值的委托类型;
2、ParameterizedThreadStart是带有一个object类型参数,没有返回值的委托类型;
如下图:
使用实例源码:
class Program
{
public static void Main(string[] args)
{
ThreadStart method = null;
Thread withoutParam = null;
//1-1无参数->ThreadStart对象初始化化线程对象
method = Sum2;//methon=new ThreadStart(Sum2) method += Sum2(多播委托)
withoutParam = new Thread(method);
withoutParam.Name = "无参数->ThreadStart对象初始化化线程对象";
withoutParam.Start();
//1-2无参数->函数初始化化线程对象
withoutParam = new Thread(Sum2) { IsBackground = true, Name = "无参数->函数初始化化线程对象" };
withoutParam.Start();
//1-3无参数->匿名函数初始化化线程对象
withoutParam = new Thread(delegate()
{
for (int i = 0; i < 5; i++)
{
if (i == 3)
Thread.CurrentThread.Abort();
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "-->" + Thread.CurrentThread.Name);
}
}) { IsBackground = true, Name = "无参数->匿名函数初始化化线程对象" };
withoutParam.Start();
//1-4无参数->Lambda表达式初始化化线程对象
withoutParam = new Thread(() =>
{
for (int i = 0; i < 5; i++)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "-->" + Thread.CurrentThread.Name);
}
},1) { IsBackground = true, Name = "Lambda表达式初始化化线程对象" };
withoutParam.Start();
ParameterizedThreadStart method2;
Thread whitParam = null;
//2-1带参数->ThreadStart对象初始化化线程对象
method2 = Sum3;
whitParam = new Thread(method2);
whitParam.Name = "**********带参数**********->->ParameterizedThreadStart对象初始化化线程对象";
whitParam.Start(2);
//2-2带参数->函数初始化化线程对象
whitParam = new Thread(Sum3) { Name = "**********带参数**********->->函数初始化化线程对象" };
whitParam.Start(3);
//2-3带参数->匿名方法初始化化线程对象
whitParam = new Thread(delegate(object para){
int count = (int)para;
for (int i = 0; i < count; i++)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":::" + Thread.CurrentThread.Name);
}
}) { Name = "**********带参数**********->匿名函数初始化化线程对象" };
whitParam.Start(1);
//2-4带参数->Lambda表达式初始化化线程对象
whitParam = new Thread((para)=>
{
int count = (int)para;
for (int i = 0; i < count; i++)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":::" + Thread.CurrentThread.Name);
}
}) { Name = "**********带参数**********->Lambda表达式初始化化线程对象" };
whitParam.Start(100);
Console.ReadKey();
}
private static void Sum2()
{
for (int i = 0; i < 5; i++)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "-->" + Thread.CurrentThread.Name);
}
}
private static void Sum3(object para)
{
int count = (int)para;
for (int i = 0; i
按这样的方式如果需要线程处理的结果怎么办?
1、定义一个线程参数类代码如下:
///
/// 线程参数
///
class ThreadParam
{
///
/// 线程处理参数
///
public int X;
///
/// 线程处理参数
///
public int Y;
///
/// Action是一个没有返回值泛型委托,用于线程处理结果回调
///
public Action CallBack;
}
2、完整示例:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("程序开始执行::*********" );
Thread whitParam = new Thread(Sum3);
ThreadParam param = new ThreadParam() { X = 10, Y = 20 };
param.CallBack = ThreadCallBack;
whitParam.Start(param);
for (int i = 0; i < 20; i++)
{
Thread.Sleep(5);
Console.WriteLine("主线程ID:"+Thread.CurrentThread.ManagedThreadId);
}
Console.ReadKey();
}
private static void ThreadCallBack(int result)
{
Thread.Sleep(10);
Console.WriteLine("线程处理结果::"+result);
}
private static void Sum3(object para)
{
ThreadParam p = para as ThreadParam;
int rsult = p.X + p.Y;
if (p.CallBack != null)
{
p.CallBack(rsult);
}
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "-->线程结束");
}
}
二、使用异步方式调用同步方法:
使用 .NET Framework 可以以异步方式调用任何方法。 要实现此操作,必须定义一个委托,此委托具有与你要调用的方法相同的签名;公共语言运行时会自动使用适当的签名为此委托定义 BeginInvoke
和 EndInvoke
方法。
A、BeginInvoke
方法启动异步调用,返回 IAsyncResult ,该结果可以获取异步调用的完成进度。
B、EndInvoke
方法获取异步调用结果,在BeginInvoke方法之后的任何地方调用,如果异步调用的方法没有执行完成,
EndInvoke方法
将阻止调用线程,直到完成异步调用。
1、使用BeginInvoke方法和EndInvoke方法进行异步调用的4种方式:
A、执行一些操作,然后调用 EndInvoke
进行阻止,直到调用完成;代码如下:
public static void Main(string[] args)
{
//声明一个泛型委托(返回值为int类型,有2个int类型参数);
//使用lambda表达式为委托赋值。该表达式sleep 1秒,然后返回2个数的和;
Func testAction = (x, y) => { Thread.Sleep(1000); return x + y; };
IAsyncResult result = testAction.BeginInvoke(10, 15, null, null);
//BeginInvoke和EndInvoke方法之间,可以执行一些其他的操作A
int sum = testAction.EndInvoke(result);//如果A的操作不需要1秒就完成,那么EndInvoke就阻塞等待,直到结果回来,程序再执行EndInvoke方法下面的代码
Console.WriteLine("异步调用的结果:" + sum);
Console.ReadKey();
}
B、使用 WaitHandle 属性获取 IAsyncResult.AsyncWaitHandle ,使用它的 WaitOne 方法阻止执行,直到 WaitHandle 收到信号,然后调用 EndInvoke;代码如下:
public static void Main(string[] args)
{
//声明一个泛型委托(返回值为int类型,有2个int类型参数);
//定义一个匿名方法为委托赋值。该方法sleep 1秒,然后返回2个数的和;
Func testAction = (x, y) => { Thread.Sleep(1000); return x + y; };
IAsyncResult result = testAction.BeginInvoke(10, 15, null, null);
//BeginInvoke和EndInvoke方法之间,可以执行一些其他的操作A
result.AsyncWaitHandle.WaitOne();
int sum = testAction.EndInvoke(result);//如果A的操作不需要1秒就完成,那么EndInvoke就阻塞等待,直到结果回来,程序再执行EndInvoke方法下面的代码
Console.WriteLine("异步调用的结果:" + sum);
result.AsyncWaitHandle.Close();
Console.ReadKey();
}
C、对由BeginInvoke
返回 IAsyncResult的IsCompleted 进行轮询,以确定异步调用完成的时间,然后调用 EndInvoke
。代码如下:
public static void Main(string[] args)
{
//声明一个泛型委托(返回值为int类型,有2个int类型参数);
//定义一个匿名方法为委托赋值。该方法sleep 1秒,然后返回2个数的和;
Func testAction = (x, y) => { Thread.Sleep(1000); return x + y; };
IAsyncResult result = testAction.BeginInvoke(10, 15, null, null);
//BeginInvoke和EndInvoke方法之间,可以执行一些其他的操作A
while (!result.IsCompleted)
{
Console.Write("*");
Thread.Sleep(250);
}
int sum = testAction.EndInvoke(result);//如果A的操作不需要1秒就完成,那么EndInvoke就阻塞等待,直到结果回来,程序再执行EndInvoke方法下面的代码
Console.WriteLine("异步调用的结果:" + sum);
Console.ReadKey();
}
D、将回调方法的委托传递到 BeginInvoke
。 异步调用完成后在 ThreadPool 线程上执行TestCallBack方法。 在TestCallBack方法中调用 EndInvoke。代码如下:
public static void Main(string[] args)
{
//声明一个泛型委托(返回值为int类型,有2个int类型参数);
//定义一个匿名方法为委托赋值。该方法sleep 1秒,然后返回2个数的和;
Func testAction = (x, y) => { Thread.Sleep(1000); return x + y; };
//声明一个委托
AsyncCallback callBack =TestCallBack;
IAsyncResult result = testAction.BeginInvoke(10, 15, callBack, "I am call back param");
// IAsyncResult result = testAction.BeginInvoke(10, 15, TestCallBack, "I am call back param");
Console.ReadKey();
}
public static void TestCallBack(IAsyncResult ar)
{
AsyncResult result = (AsyncResult)ar;
Func caller = (Func)result.AsyncDelegate;
string parameter = (string)ar.AsyncState;
Console.WriteLine(parameter);
Console.WriteLine("异步方法的处理结果结果:" + caller.EndInvoke(ar));
}
总结:调用线程需要对异步处理结果进行处理可以使用的方式:A、B、C。如果调用线程不需要处理异步结果,则使用D方式。在ThreadPool线程中调用CallBack方法,对异步结果进行处理。