C# .Net学习笔记—— 异步和多线程(Async和Sync)
一、概念
进程:一个程序运行时,占用的全部计算资源的总和
线程:1、程序执行流的最小单位;任何操作都是由线程完成的
? ? ? ? ? ?2、线程是依托于进程存在的,一个进程可以包含多个线程;
? ? ? ? ? ?3、线程也可以有自己的计算资源
多线程:多个执行流同时运行
? ? ? ? ? ? 1、CPU太快了,分时间片-一上下文切换(加载环境--计算-一保存环境)
微观角度,一个核同一时刻只能执行一个线程;宏观的来说是多线程并发
? ? ? ? ? ? ?2、多CPU多核可以独立工作
? ? ? ? ? ? ? ? ? ?4核8线程一核是物理的核线程是指虚拟核
同步:完成计算之后,再进入下一行
异步:不会等待方法的完成,会直接进入下一行非阻塞
C#异步和多线程有什么差别
多线程就是多个thread并发;
异步是硬件式的异步
异步多线程-thread pool task
二、同步异步简单案例
private void buttonSync_Click(object sender, EventArgs e)
{
Log.Info($"S Start {Thread.CurrentThread.ManagedThreadId}");
int j = 3;
int k = 5;
int m = j + k;
for (int i = 0; i < 5; i++)
{
string name = string.Format($"**********S{i}*************");
this.DoSomethingLong(name);
}
Log.Info($"S End");
}
private void buttonAsync_Click(object sender, EventArgs e)
{
Log.Info($"\nA Start {Thread.CurrentThread.ManagedThreadId}");
Action<string> action = this.DoSomethingLong;
for (int i = 0; i < 5; i++)
{
string name = string.Format($"**********A{i}*************");
action.BeginInvoke(name, null, null);
}
Log.Info($"A End");
}
private void DoSomethingLong(string name)
{
Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
long result = 0;
for (int i = 0; i < 100000000; i++)
{
result += i;
}
Thread.Sleep(2000);
Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
}
?同步:
?异步:
?
从打印结果来看也能反映出,
同步:1、完成计算之后,再进入下一行。
? ? ? ? ? ?2、同步方法卡界面,主(UI)线程忙于计算。
? ? ? ? ? ?3、同步方法慢,只有一个线程干活
异步:1、不会等待方法的完成,会直接进入下一行非阻塞。? ? ? ? ? ?2、异步多线程方法不卡界面,主线程完事,计算任务交给子线程在做。
? ? ? ? ? ?3、异步多线程方法快,因为多个线程并发运算
? ? ? ? ? ?4、异步并不是线性增长,而是资源换时间,多线程也有管理成本
? ? ? ? ? ?5、提升用户体验
? ? ? ? ? ?6、并不是越多越好
? ? ? ? ? ?7、最好是多个独立任务同时进行的使用
异步等待方式1:异步回调:
private void buttonAysncCallback_Click(object sender, EventArgs e)
{
Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
Action<string> action = this.DoSomethingLong;
AsyncCallback callback = ia => Log.Info($"计算完成。{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
action.BeginInvoke("AysncCallBack", callback, null);
Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
}
从结果来看,异步回调action.BeginInvoke()可以得到一个AsyncCallBack,然后这个callBack再执行的委托。这样可以有效的控制我们线程的次序。
缺点:我想要全部计算都完成了再给用户返回结果,这种方法实现不了
异步等待方式2:线程等待
asyncResult.AsyncWaitHandle.WaitOne(); //等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(); //等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(1000); //等待;但是最多等待1000ns
? 异步等待方式3:?EndInvoke()
private void buttonTest_Click(object sender, EventArgs e)
{
Func<int> func = () =>
{
Thread.Sleep(2000);
return DateTime.Now.Day;
};
Console.WriteLine($"func.Invoke()={func.Invoke()}");
IAsyncResult asyncResult = func.BeginInvoke(r =>
{
Console.WriteLine(r.AsyncState);
}, "哈啊哈哈");
Console.WriteLine($"func.EndInvoke(asyncResult) = {func.EndInvoke(asyncResult)}");
}
?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!