栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C#多线程Task注意事项

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#多线程Task注意事项

学习过程:C#多线程的写法有很多,网上都能搜到,各有优劣。作为新手,最讨厌网上那种类似“多线程的5种方式”之类的文章,我不可能5中方式都使用一遍,我只需要其中一种最合适的。
代老师推荐向我Task类。下面是我个人对它的理解:

1、编程效率高,但损失性能
Task是Thread的升级版,会更好用。编程方便,代码量少。Task会帮你管理线程,程序员只要把握好什么时候启动线程,其他不需要操心。什么时候关闭线程、线程是否是后台线程等都是系统自己处理。强大的功能,肯定会降低效率。大部分程序不用考虑这点微乎其微的性能损失。大型互联网项目,一般也不会使用C#去写。就像初学try{}catch{}的时候,也说它会降低性能,但是项目中,几乎每个方法都写了try{}catch{},用来记录报错Log,性能影响微乎其微,可以忽略不计。
下面是2中Task启动线程的常用写法:

//写法1:
Task.Run(TestShow);

//方法2:
Task.Run(() =>
{
	
});

写法1,适用于调用单个无参方法;
写法2,适用于调用多行代码块;

2、线程启动有延迟
线程启动有几十毫秒时间延迟,并不是立即启动。下面是测试代码和结果:

using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            Task.Run(() =>
            {
                Stopwatch sw2 = new Stopwatch();
                sw2.Start();
                //线程代码主体
                sw2.Stop();
                Console.WriteLine("执行线程耗时:" + sw2.ElapsedMilliseconds);
            });
            sw1.Stop();
            Console.WriteLine("Task启动耗时:" + sw1.ElapsedMilliseconds);
            Console.ReadKey();
        }
    }
}

执行代码的耗时,取决于代码块的内容。但是启动线程需要花27ms(这个时间不是固定的,跟设备、时机等多种因素相关。)

3、线程启动顺序随机
主线程按顺序写了9 个线程,代码执行的过程是按顺序执行了线程启动的9行代码。惯性思维,线程是顺序启动的。实际情况却不是,线程启动的顺序随机,下面是测试代码和结果:

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 9; i++)
            {
                Task.Run(TestShow);
            }
            Console.ReadKey();
        }
        static int k = 0;
        private static void TestShow()
        {
            k++;
            Console.WriteLine("线程:" + k);
        }
    }
}

这点很重要,有个项目,我想记录与PLC通讯的所有信息记录下来,又不想损耗PLC的读写效率,想到使用的Task多线程执行记录的信息,然而时间不是按顺序的记录的,查找问题异常困难,当场裂开。然后,代老师告诉我,Task的执行顺序是随机的,如果对顺序有要求,可以使用队列。

4、数据不安全
看上述范例,按照设想应该出现1~9的随机数,但是却少了一个1,多了一个3。具体怎么解决,我还没查到,代老师在居家隔离,并且在开会,他告诉我使用Interlocked,但我查了网上资料,没搞出来,下次再说。上述范例比较极端,正常人也不会让同一个任务同时被多个线程调用。

5、不用手动结束线程
多线程有2个结束方式:
a、线程代码运行结束,线程自动结束并自动销毁;
b、手动中止并销毁;
写代码时,尽可能避免手动中止。没有死循环的代码,会按照方式a的操作,执行完成后结束线程。如果在线程中出现了while等死循环,尽量用变量控制它自然结束,按照方式a的操作,执行完成后结束线程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023296.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号