发布:2019/12/17 16:30:06作者:管理员 来源:本站 浏览次数:1166
下面我用代码使用Thread类实现线程等待,回调,前台线程/后台线程
首先我们需要先定义一个比较消耗资源的方法用来跑线程
/// <summary>
/// 一个比较耗时耗资源的私有方法
/// </summary>
/// <param name="name"></param>
private void DoSomethingLong(string name)
{
Console.WriteLine($"****************DoSomethingLong {name} Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
long lResult = 0;
for (int i = 0; i < 1000000000; i++)
{
lResult += i;
}
//Thread.Sleep(2000);
Console.WriteLine($"****************DoSomethingLong {name} End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
}
Thread初始化方式:
Thread初始化不能直接使用Action传入,但可使用ThreadStart,其实ThreadStart的功能跟Action差不多,只是为了.NET版本向前兼容的缘故,而一直没改动。
Action action = () => this.DoSomethingLong("btnThreads_Click");
ThreadStart threadStart = () => this.DoSomethingLong("btnThreads_Click");
//Thread thread = new Thread(action);//不可以这样初始化
Thread thread = new Thread(() => this.DoSomethingLong("btnThreads_Click"));
Thread thread2 = new Thread(threadStart);
Thread的基本操作
Thread thread = new Thread(() => this.DoSomethingLong("btnThreads_Click"));
//1、线程启动
thread.Start();
//thread.Suspend();//线程挂起_已弃用
//thread.Resume();//唤醒线程_已弃用
//2、线程销毁
try
{
thread.Abort();//销毁,方式是抛异常 也不建议 不一定及时/有些动作发出收不回来
}
catch (Exception)
{
Thread.ResetAbort();//取消Abort异常
}
//3、线程等待
thread.Join(500);//最多等500
Console.WriteLine("等待500ms");
thread.Join();//当前线程等待thread完成
//4、判断线程是否停止
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(100);//当前线程 休息100ms
}
//5、设置后台线程
//默认是前台线程,启动之后一定要完成任务的,阻止进程退出
thread.IsBackground = true;//指定后台线程:随着进程退出
//6、设置线程优先级
thread.Priority = ThreadPriority.Highest;//线程优先级
//CPU会优先执行 Highest 不代表说Highest就最先
前台线程跟后台线程的区别:
Thread默认是前台线程,启动之后一定要完成任务的,阻止进程退出,就是一定要线程运行完毕进程才会退出。
而后台线程则随着进程的退出线程也跟着退出。
Thread的前台多线程并发
/// <summary>
/// Thread前台多线程并发
/// </summary>
private void ForegroundThreads()
{
Console.WriteLine($"****************开始前台多线程并发 {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
for (int i = 0; i < 5; i++)
{
new Thread(() => this.DoSomethingLong("开始前台多线程并发")).Start();
}
}
Thread的后台多线程并发
/// <summary>
/// Thread后台多线程并发
/// </summary>
private void BackgroundThreads()
{
Console.WriteLine($"***************开始后台多线程并发 {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(() => this.DoSomethingLong("开始后台多线程并发"));
thread.IsBackground = true;
thread.Start();
}
}
Thread的线程回调委托
//启动子线程计算--完成委托后,该线程去执行后续回调委托
private void ThreadWithCallback(Action act, Action callback)
{
Thread thread = new Thread(() =>
{
act.Invoke();
callback.Invoke();
});
thread.Start();
}
// Thread线程回调委托
private void UseThreadCallback()
{
this.ThreadWithCallback(() => Console.WriteLine($"这里是主线程执行 {Thread.CurrentThread.ManagedThreadId.ToString("00")}")
, () => Console.WriteLine($"这里是回调执行 {Thread.CurrentThread.ManagedThreadId.ToString("00")}"));
}
Thread的带返回值的异步调用
/// <summary>
/// 又要结果 要不阻塞
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
private Func<T> ThreadWithReturn<T>(Func<T> func)
{
T t = default(T);
Thread thread = new Thread(() =>
{
t = func.Invoke();
});
thread.Start();
return () =>
{
thread.Join();
return t;
};
}
//带返回的异步调用 需要获取返回值
private int UseThreadReturn()
{
Func<int> func = this.ThreadWithReturn<int>(() =>
{
Thread.Sleep(2000);
return DateTime.Now.Millisecond;
});
return func.Invoke();
}