加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C# 实现线程的常用几种方式

发布时间:2020-12-16 01:05:12 所属栏目:百科 来源:网络整理
导读:前言 在各个开发语言中,线程是避免不了的,或许通过表象看不出来,但是真的无处不在。就比如一个Web程序,平时或许只注重增删改查的开发,根本没有编写相关多线程的的代码,但是请求内部的时候,已经分配了对应线程进行处理了,以下简单说说C#中使用线程的

前言

  在各个开发语言中,线程是避免不了的,或许通过表象看不出来,但是真的无处不在。就比如一个Web程序,平时或许只注重增删改查的开发,根本没有编写相关多线程的的代码,但是请求内部的时候,已经分配了对应线程进行处理了,以下简单说说C#中使用线程的几种方式,详细使用后续继续记录。

Thread类实现

  Thread类的实现方式,在C# .NetFramework刚出的时候就已经存在了,起初刚开始的程序员都使用这种方式,但经历后面几个.NetFramework的版本更新,实现方式变的更多了。

     public void TestThread()
        {
            //这里需要注意的是:在C#中线程是离不开委托的
            创建了一个线程对象,这里构造函数提供两类,一种不带参数的,一种是带参数的
            Thread thread = new Thread( TestAction);
            设置线程相关属性
            thread.IsBackground = true;
            thread.Name = "Test";
            启动线程
            thread.Start();
        }

        /// <summary>
        /// 线程执行的方法
        </summary>
        private  TestAction()
        {
            这里实现线程处理的相关业务
            Console.WriteLine($子线程Thread({Thread.CurrentThread.Name})执行相关业务操作....{Thread.CurrentThread.ManagedThreadId});
        }

运行结果:

?

?ThreadPool 线程池实现

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace MutltiThreadImplement
{
    /// <summary>
    /// ThreadPool 池化线程,避免频繁的申请和释放消耗资源;之前Thread每次都要申请和释放。
    /// </summary>
    public class ThreadPoolImplement
    {
        public void TestThreadPool()
        {
            //可以设置相关属性
            ThreadPool.SetMinThreads(5,10);
            ThreadPool.SetMaxThreads(6,10);

            //通过线程池自动分配线程执行对应的业务功能
            ThreadPool.QueueUserWorkItem(TestAction);
            
            
        }

        private void TestAction(object state)
        {
            //这里实现线程处理的相关业务
            Console.WriteLine($"子线程Thread({Thread.CurrentThread.Name})执行相关业务操作....{Thread.CurrentThread.ManagedThreadId}");
        }
    }
}

  

  运行结果:

?

?

? ? ?ThreadPool的使用是不是感觉比较简单,但是就是因为太简单了,在业务中有些需求得不到满足,比如试着控制线程顺序;

Delegate 实现的多线程

     TestDelegateThread()
        {
            定义一个强类型委托, 可以自定义委托
            Action action = TestAction;

            开始异步操作,其实内部是开启了子线程,看线程id不一样就明白了
            IAsyncResult asyncResult = action.BeginInvoke(CallBack,null);

            可以根据返回对象的一些属性和方法进行判断和业务逻辑执行  具体可以查看相关文档
            asyncResult.IsCompleted; 判读是否执行完成
            asyncResult.AsyncWaitHandle.WaitOne(); 阻塞当前线程,直到收到信号量
        }

        );
        }

         子线程执行完成时的回调
         CallBack(IAsyncResult ar)
        {
            Console.WriteLine($子线程{Thread.CurrentThread.ManagedThreadId}执行完毕);
        }    

运行结果:

  

?

?注:? 这种方式在.NetCore环境不支持,提示平台不支持。

BackGroundWorker 实现

    BackgroundWorker backgroundWorker =      BackgroundWorker();

         TestBackGroundWorker()
        {
            
            这里使用的是事件的方式绑定业务处理方法
            backgroundWorker.DoWork +=可以绑定一些事件    使用很简单,可以不需要绑定以下事件和设置属性就可以执行,根据需要进行绑定
            执行完成事件
            backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
            backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
            backgroundWorker.WorkerReportsProgress = true;只有执行这个属性之后才能进行ProgressChanged触发


            开始执行操作
            backgroundWorker.RunWorkerAsync();
        }

         触发事件之后的业务处理
        void BackgroundWorker_ProgressChanged(object sender,ProgressChangedEventArgs e)
        {
            Console.WriteLine(可以在这里更新UI线程上的东西....void BackgroundWorker_RunWorkerCompleted(子线程{Thread.CurrentThread.ManagedThreadId}执行完成!!!);
        }

        void TestAction();
            在业务方法中执行ReportProgress方法会触发ProgressChanged事件
            backgroundWorker.ReportProgress(10);
            Console.WriteLine($子线程Thread({ Thread.CurrentThread.ManagedThreadId})执行相关业务操作结束);
        }    

运行结果:

?

BackgroundWorker 这种方式比较适应于窗体应用程序。

Task 实现多线程

         Task 实现多线程, 目前为止,Task方式是大家都比较推荐的方式
         TestTask()
        {
            创建一个Task实例
            Task task =  Task(TestAction);
            开始任务
            task.Start();
        }

        );
        }    

运行结果

?

?Task实现多线程的方式是大家一致推荐的,俗称最佳实践。

Parallel实现多线程

    <summary>
     Parallel 是对Task的进一步封装,但会阻塞主线程,主线程会参与业务逻辑处理
    </summary>
    class ParallelImplement
    {
         TestParallel()
        {
            //分配线程执行业务逻辑,? Invoke可传多个业务处理,内部会自动分配线程处理
            Parallel.Invoke(TestAction);
        }
        );
        }
    }

运行结果:

 

?

?根据运行结果得出结论,主线程参与业务逻辑处理中,会阻塞线程, Parallel可根据业务进行选择使用。

?

总结

  以上基本上就是C#中使用多线程常用的几种方式,这里只是简单的汇总方式,没有深入分析,后续将针对模块进行分析。

?

?

?

 

?

  

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读