多线程目的:
为了最大化发挥多核处理器的性能,使应用程序中的任务能够得到高效率执行。让任务响应更加迅速.
多线程的实现方式:
1,实例化Thread类,这种方式称之为专用线程,默认是前台线程,start之后不会被迫关闭,应用程序只会在线程任务执行完成之后关闭,在进程结束时或者任务完成时会被回收。如果创建的Thread指定为后台线程, 应用程序可以不考虑线程任务是否执行完而强制关闭线程,前台和后台线程主要区分在于回收上,一个没权强制回收,一个有权强制回收。实例化代码:
Thread thread = new Thread(new ThreadStart(() => {
while (true)
{
Console.WriteLine("这是一个测试线程");
Thread.Sleep(2000);
}
}));
// thread.IsBackground = true;
thread.Start();
while (true)
{
Console.WriteLine("这是一个测试线程");
Thread.Sleep(2000);
}
}));
// thread.IsBackground = true;
thread.Start();
2,ThreadPool创建,这种方式的优势在于不用去管理线程的生命周期,用.net框架给我制定好的线程池为我们执行多线程操作。这种操作相当简单,但非常高效。
ThreadPool.QueueUserWorkItem((x) => {
while (true)
{
Console.WriteLine("这是测试线程池"+x);
Thread.Sleep(2000);
}
},5);
while (true)
{
Console.WriteLine("这是测试线程池"+x);
Thread.Sleep(2000);
}
},5);
3,异步委托方式,异步委托适用于主业务中去调用第三方服务的场景。比如下订单之后需要给客户发送短信或者邮件通知,此时可以通过异步委托的方式去执行第三方接口,主业务不会等待第三方接口的返回值。
delegate TResult Func<TArg, TResult>(TArg arg);
public void DelegateTest()
{
Func<string, string> func = x => {
Console.WriteLine("这是测试委托" + x);
Thread.Sleep(2000);
return "这是返回值";
};
func.BeginInvoke("这是参数", (x) =>
{
if (x.IsCompleted)
{
Console.WriteLine("这是回调函数" + func.EndInvoke(x));
}
}, func);
}
public void DelegateTest()
{
Func<string, string> func = x => {
Console.WriteLine("这是测试委托" + x);
Thread.Sleep(2000);
return "这是返回值";
};
func.BeginInvoke("这是参数", (x) =>
{
if (x.IsCompleted)
{
Console.WriteLine("这是回调函数" + func.EndInvoke(x));
}
}, func);
}
4,Task编程模型,Task编程模型越来越受到微软的重视,从最新的api能看的出来,对于一些IO密集型操作,Task编程能让应用程序性能得以提升。
一个简单的Task
public Task<string> TaskTest()
{
return Task.Run(() =>
{
Thread.Sleep(2000);
return "";
});
}
{
return Task.Run(() =>
{
Thread.Sleep(2000);
return "";
});
}
5,TaskFactory创建新的线程,类似于线程池,对Task的创建通过工厂来实现
public void TaskFactory()
{
var task= Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("这是TaskFactory创建线程");
Thread.Sleep(2000);
return "这是返回值";
});
Console.WriteLine(task.Result);
}
{
var task= Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("这是TaskFactory创建线程");
Thread.Sleep(2000);
return "这是返回值";
});
Console.WriteLine(task.Result);
}
Task编程是非常重要的一个编程方式,用得好,能让应用性能得到提升,用的不好,程序会变得晦涩难懂,维护起来非常困难,微软提供了 async和await来实现上下文的一个同步。让异步代码看着像同步代码一般,把回调从链式编程的坑中解放出来。熟悉js的同学都知道回调函数的嵌套可以也可以通过 await去等待当前线程的返回结果,但却不会阻塞UI。其实编程时间长了,就回发现,很多时候不同语言之前处理问题的思路大体上还是差不多的。
public async Task<string> TaskTest()
{
Console.WriteLine("Task开始");
var task = await Task.Run(() =>
{
Console.WriteLine("这是Task");
Thread.Sleep(2000);
return "";
});
Console.WriteLine("Task结束");
return task;
}
{
Console.WriteLine("Task开始");
var task = await Task.Run(() =>
{
Console.WriteLine("这是Task");
Thread.Sleep(2000);
return "";
});
Console.WriteLine("Task结束");
return task;
}
这是在当前代码段中通过await 去等待一个task任务执行完,await的标记一个可以另起一个线程的方法,返回值必定是task,或者是task泛型。执行结果是
此时将async和await去掉,执行结果是
我所知道的五种创建线程的方式就是这么多,个人比较喜欢Task编程模型,有时间了会专门把这一块总结一下。