SeeSharper - csharp
type: channel
link: https://seesharper.cn/tag/csharp/
items: 【ASP.NET Core开发者学习路线】 2.1 C#基础—多线程
items: ElasticSearch聚合之按照某字段分组统计另一字段总和

【ASP.NET Core开发者学习路线】 2.1 C#基础—多线程
type: item
date: 2023-05-19T07:27:00+00:00
description: 引言在现代软件开发中，多线程编程变得越来越重要。通过充分利用多核处理器的优势，我们可以提高应用程序的性能和响应能力。在.NET平台上，多线程编程变得相对容易，并提供了丰富的工具和库来帮助我们实现并发操作。本篇博客将向您介绍如何在.NET中进行多线程编程，并提供通俗易懂的解释和代码示例。1. 什么是多线程？在计算机科学中，线程是一种执行单元，它可以在程序中独立运行。一个线程可以执行一系列指令，而不受其他线程的干扰。多线程编程指的是同时执行多个线程以实现并发操作。2. 为什么使用多线程？使用多线程可以带来以下好处：提高性能: 多线程允许我们同时执行多个任务，从而加快程序的执行速度。提高响应能力: 在GUI应用程序中，使用多线程可以避免主线程被阻塞，使用户界面保持响应，同时在后台执行任务。提高资源利用率: 当一个线程被阻塞时，另一个线程可以继续执行，充分利用CPU和其他系统资源。3. 在.NET中创建和启动线程在.NET中，我们可以使用System.Threading.Thread类创建和启动线程。以下是创建和启动线程的示例代码：csharpCopy codeusing System; using System.Threading; class Program { static void Main() { // 创建一个新线程并指定执行的方法 Thread thread = new Thread(DoWork); // 启动线程 thread.Start(); // 主线程继续执行其他任务 Console.WriteLine("Main thread is doing some work..."); // 等待线程完成 thread.Join(); Console.WriteLine("Thread completed!"); } static void DoWork() { // 在这里编写线程执行的代码 Console.WriteLine("Thread is doing some work..."); Thread.Sleep(2000); // 模拟线程执行耗时操作 } }上述代码创建了一个新线程，并使用DoWork方法作为线程的执行方法。Thread.Start方法用于启动线程，而Join方法用于等待线程完成。请注意，在主线程中我们可以继续执行其他任务，而不必等待新线程完成。4. 同步与互斥在多线程编程中，同步和互斥是两个重要的概念。同步指的是协调线程之间的执行顺序，而互斥指的是控制线程对共享资源的访问。4.1 同步在.NET中，可以使用lock语句实现线程的同步。lock语句用于获取指定对象的互斥锁，以确保只有一个线程可以访问被保护的代码块。以下是一个使用lock语句实现同步的示例：csharpCopy codeusing System; using System.Threading; class Program { static int count = 0; static object lockObject = new object(); static void Main() { Thread thread1 = new Thread(IncrementCount); Thread thread2 = new Thread(IncrementCount); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); Console.WriteLine("Count: " + count); } static void IncrementCount() { for (int i = 0; i < 1000000; i++) { lock (lockObject) { count++; } } } }在上述代码中，我们使用了一个静态变量count作为共享资源，并创建了两个线程来增加该计数器的值。通过使用lock (lockObject)语句，我们确保只有一个线程可以同时访问count变量，从而避免竞态条件（race condition）。4.2 互斥除了使用lock语句外，.NET还提供了更高级的互斥机制，如Monitor类和Mutex类。这些类可以用于实现更复杂的同步和互斥需求。下面是一个使用Mutex类实现互斥的示例：csharpCopy codeusing System; using System.Threading; class Program { static int count = 0; static Mutex mutex = new Mutex(); static void Main() { Thread thread1 = new T…

ElasticSearch聚合之按照某字段分组统计另一字段总和
type: item
date: 2022-09-05T08:33:00+00:00
description: 需求将课程包按照学科分组，分别统计各学科下的课程小节数量数据格式{ "subject" : 1001, //学科 "teacherIds" : "62c522aabb72127914f7bcd7", "type" : -1, "version" : -1, "imgUrl" : "", "hits" : 258, "createdAt" : "2022-07-07T16:41:31.9609245+08:00", "isDeleted" : false, "grade" : 1040, "intro" : "优秀特级教师", "name" : "高一语文上学期同步课（通用版）", "id" : "68652741-6b6c-4171-89c3-a5734a9c8ed2", "courseId" : 1000422852, "status" : 1, "sectionNum":25, //课程小节数量 "updatedAt" : "2022-07-07T08:41:31.9605212+00:00" }ES代码POST youzy_applib_aliyun_course/_search { "size": 0, "aggs": { "subjet": { "terms": { "field": "subject", //按照学科分组 "size": 1000 }, "aggs": { "coun": { "sum": { "field": "sectionNum" //用sum去总数 } } } } } } c#翻译 public async Task<IList<CourseSubjectStatsViewDto>> GetSubjectStats() { var conditions = new List<Func<QueryContainerDescriptor<Course_ES>, QueryContainer>>() { x => x.Term(t => t.Field(f => f.IsDeleted).Value(false)), x => x.Term(t => t.Field(f => f.Status).Value(1)) }; var query = await Client.SearchAsync<Course_ES>(x => x.Index(IndexName) .Query(q => q.Bool(b => b.Must(conditions))) .Size(0) .Aggregations(agg => agg.Terms("subject", sel => sel.Field(f => f.Subject) .Aggregations(agg2 => agg2.Sum("sections", sel2 => sel2.Field(f => f.SectionNum))) ))); var result = new List<CourseSubjectStatsViewDto>(); var subjectAgg = (BucketAggregate)query.Aggregations.First(x => x.Key == "subject").Value; var buckets = subjectAgg.Items.Select(x => (KeyedBucket )x).ToList(); foreach (var bucket in buckets) { result.Add(new CourseSubjectStatsViewDto() { Subject = bucket.Key.ToInt(), Count = ((ValueAggregate)bucket.Values.First()).Value.ToInt() }); } result = result.OrderBy(x => x.Subject).ToList(); return result; }