设为首页 加入收藏

TOP

Threads(异步和多线程)(三)
2019-09-23 11:16:38 】 浏览:129
Tags:Threads 异步 线程
ist
= taskList.Where(t => t.Status != TaskStatus.RanToCompletion).ToList(); } taskList.Add(Task.Run(() => { Console.WriteLine($"This is {k} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}"); Thread.Sleep(2000); })); }

 

Parallel并发执行多个Action线程,主线程会参与计算---阻塞界面。等于TaskWaitAll+主线程计算

 Parallel.Invoke(() => this.DoSomethingLong("btnParallel_Click_1"),
     () => this.DoSomethingLong("btnParallel_Click_2"),
     () => this.DoSomethingLong("btnParallel_Click_3"),
     () => this.DoSomethingLong("btnParallel_Click_4"),
     () => this.DoSomethingLong("btnParallel_Click_5"));
Parallel.For(0, 5, i => this.DoSomethingLong($"btnParallel_Click_{i}"));
Parallel.ForEach(new int[] { 0, 1, 2, 3, 4 }, i => this.DoSomethingLong($"btnParallel_Click_{i}"));

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 3;
Parallel.For(0, 10, options, i => this.DoSomethingLong($"btnParallel_Click_{i}"));

有没有办法不阻塞?

Task.Run(() =>
{
    ParallelOptions options = new ParallelOptions();
    options.MaxDegreeOfParallelism = 3;
    Parallel.For(0, 10, options, i => this.DoSomethingLong($"btnParallel_Click_{i}"));
});

  几乎90%以上的多线程场景,以及顺序控制,以上的Task的方法就可以完成,如果你的多线程场景太复杂搞不定,那么请梳理一下你的流程,简化一下。建议最好不要线程嵌套线程,两三次勉强能懂,三层就hold不住了,更多的只能求神。

 

多线程异常:

try
{

    List<Task> taskList = new List<Task>();
    for (int i = 0; i < 100; i++)
    {
        string name = $"btnThreadCore_Click_{i}";
        taskList.Add(Task.Run(() =>
        {
            if (name.Equals("btnThreadCore_Click_11"))
            {
                throw new Exception("btnThreadCore_Click_11异常");
            }
            else if (name.Equals("btnThreadCore_Click_12"))
            {
                throw new Exception("btnThreadCore_Click_12异常");
            }
            else if (name.Equals("btnThreadCore_Click_38"))
            {
                throw new Exception("btnThreadCore_Click_38异常");
            }
            Console.WriteLine($"This is {name}成功 ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}");
        }));
    }
    //多线程里面抛出的异常,会终结当前线程;但是不会影响别的线程;
    //那线程异常哪里去了? 被吞了,
    //假如我想获取异常信息,还需要通知别的线程
    Task.WaitAll(taskList.ToArray());//1 可以捕获到线程的异常
}
catch (AggregateException aex)//2 需要try-catch-AggregateException
{
    foreach (var exception in aex.InnerExceptions)
    {
        Console.WriteLine(exception.Message);
    }
}
catch (Exception ex)//可以多catch  先具体再全部
{
    Console.WriteLine(ex);
}
//线程异常后经常是需要通知别的线程,而不是等到WaitAll,问题就是要线程取消
//工作中常规建议:多线程的委托里面不允许异常,包一层try-catch,然后记录下来异常信息,完成需要的操作

线程取消:

                //多线程并发任务,某个失败后,希望通知别的线程,都停下来,how?
                //Thread.Abort--终止线程;向当前线程抛一个异常然后终结任务;线程属于OS资源,可能不会立即停下来
                //Task不能外部终止任务,只能自己终止自己(上帝才能打败自己)

                //cts有个bool属性IsCancellationRequested 初始化是false
                //调用Cancel方法后变成true(不能再变回去),可以重复cancel
                try
                {
                    CancellationTokenSource cts = new CancellationTokenSource();
                    List<Task> taskList = new List<Task>();
                    for (int i = 0; i < 50; i++)
                    {
                        string name = $"btnThreadCore_Click_{i}";
                        taskList.Add(Task.Run(() =>
                        {
                            try
                            {
                                if (!cts.IsCancellationRequested)
                                    Console.WriteLine($"This
首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C#程序员在老项目中用到VB遇到的.. 下一篇C#面向对象之继承

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目