隐藏

C#/.NET Thread类实现线程等待,回调,多线程并发操作

发布: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();
}