您的位置:首页 > 其它

.Net进阶系列(12)-异步多线程(Thread和ThreadPool)(被替换)

2017-06-23 19:59 741 查看
[b]一. Thread多线程[/b]

1. 两种使用方式

  通过F12查看Thread后,发现有两类构造函数,ParameterizedThreadStart和ThreadStart,其中

    ThreadStart:无参无返回值的委托

    ParameterizedThreadStart:无返回值,但是有一个object类型参数的委托

下面Thread的使用都是围绕上面这两个构造函数来进行的。

方式一:(当委托是无参数,但赋值的方法又是有参数的,可以使用这种方式转换)

当只有一行的时候,可以省略{},实际上和下面一个道理

{
ThreadStart tStart = () => TestThread("参数1", "参数2");
//ThreadStart tStart2 = () =>
//{
//    TestThread("参数1", "参数2");
//};
Thread thread = new Thread(tStart);
thread.Start();
}


方式二:(当委托是有一个object参数的时候, 如果赋值的方法不是只有一个参数,将不适用与该委托)不推荐这种方式,存在拆箱和装箱问题,效率低

{
ParameterizedThreadStart pStart = t => TestThread2(t.ToString());
//ParameterizedThreadStart pStart2 = (t) => TestThread2(t.ToString());
//ParameterizedThreadStart pStart3 = (t) =>
//{
//    TestThread2(t.ToString());
//};
Thread thread = new Thread(pStart);
thread.Start("参数1");
}


 2. 利用Join方法进行线程等待

{
List<Thread> list = new List<Thread>();
for (int i = 0; i < 5; i++)
{
string name1 = string.Format("ypf1-{0}", i);
string name2 = string.Format("ypf2-{0}", i);
ThreadStart tStart = () => TestThread(name1, name2);
Thread thread = new Thread(tStart);
list.Add(thread);
thread.Start();
}
//线程等待
foreach (var item in list)
{
item.Join();
}
}


 3. 补充:可以利用IsBackground设置是否为后台线程



[b]二. ThreadPool多线程[/b]

1. 使用方式

ThreadPool开启线程唯一的方式就是 ThreadPool.QueueUserWorkItem() ,QueueUserWorkItem的参数为WaitCallback,WaitCallback为有一个object类型参数的无返回值的委托,那么该委托将怎么应对,无参数函数、一个参数的函数、多个参数的函数。

//1. 没有参数
{
WaitCallback wcl = t => TestThread3();
ThreadPool.QueueUserWorkItem(wcl);
}
//2. 一个参数
{
WaitCallback wcl = t => TestThread2(t.ToString());
ThreadPool.QueueUserWorkItem(wcl, "测试参数1");
}
//3. 两个参数
{
//因为WaitCallback委托没法结束有两个参数的方法,这里我们采用将方法封装到类中的方式解决
MyTest<string, string> model = new MyTest<string, string>("测试参数1", "测试参数2");
WaitCallback wcl = (t) =>
{
model.TestThread();
};
ThreadPool.QueueUserWorkItem(wcl);
}


public class MyTest<T,M>
{
public T msg1 { get; set; }
public M msg2 { get; set; }
public MyTest(T t1,M m1)
{
this.msg1 = t1;
this.msg2 = m1;
}
public  void TestThread()
{
Console.WriteLine("线程开始:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId);
long sum = 0;
for (int i = 1; i < 999999999; i++)
{
sum += i;
}
Console.WriteLine("线程结束:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId);
}
}


  2. 多线程等待

      List<ManualResetEvent> list = new List<ManualResetEvent>();
for (int i = 0; i < 5; i++)
{
ManualResetEvent mr = new ManualResetEvent(false);
WaitCallback wcl = t =>
{
TestThread2(t.ToString());
mr.Set(); //将该线程设置为终止状态
};
list.Add(mr);
ThreadPool.QueueUserWorkItem(wcl, "测试参数1");
}
foreach (var item in list)
{
item.WaitOne();
}


  3. 线程池的基本设置

{
//1.设置最大和最小线程数
ThreadPool.SetMaxThreads(8, 8);
ThreadPool.SetMinThreads(4, 4);
//2.工作线程和IO线程最大值和最小值的获取(注释掉上面的设置,然后看下面的获取结果)
int workerThreads;
int ioThreads;
{
ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Max worker threads: {0};    Max I/O threads: {1}", workerThreads, ioThreads));
}
{
ThreadPool.GetMinThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Min worker threads: {0};    Min I/O threads: {1}", workerThreads, ioThreads));
}
{
ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);
Console.WriteLine(String.Format("Available worker threads: {0};    Available I/O threads: {1}", workerThreads, ioThreads));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐