• 异步编程学习


    摘抄自文章:.NET中的异步编程

    异步编程中重要的技术点在于:

    1)当异步线程在工作完成时,如何通知调用线程?

    2)当异步线程出现异常的时,该如何处理?

    3)异步线程工作的进度,如何实时的通知调用线程?

    4)如何在调用线程中,取消正在工作的异步线程,并进行回滚操作?

    完整的异步调用例子:

    class Program
        {
            public delegate int DoWord(int count);
            static void Main(string[] args)
            {
                DoWord d = new DoWord(WorkPro);
                IAsyncResult r= d.BeginInvoke(100,CallBack ,d);//no.1
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(10);//主线程需要做的事
                }
                Console.WriteLine("主线程done");
                Console.ReadKey();
            }
            public static int WorkPro(int count)
            {
                int sum = 0;
                //做一些耗时的工作
                for (int i = 0; i < count; i++)
                {
                    sum += i;
                    Thread.Sleep(10);
                }
                return sum;        
            }
     
            public static void CallBack(IAsyncResult r)
            {
                DoWord d = (DoWord)r.AsyncState;
                Console.WriteLine("异步调用完成,返回结果为{0}", d.EndInvoke(r));
            }
        }

    以上被博主称之为异步函数模型。

    Thread类

    class Program
        {
            static void Main(string[] args)
            {
                Thread t = new Thread(WorkPro);//no.1
                t.IsBackground = true;//no.2
                t.Start(1000);//no.3
            }
            public static void WorkPro(object  t)
            {
                //做一些耗时的工作   
                int count=(int)t;
                for (int i = 0; i < count; i++)
                {
                    Thread.Sleep(2000);
                }
     
                Console.WriteLine("任务处理完成");
            }
        }
    Thread类的使用虽然简单,但是它还是有一定的劣势的,一般不推荐使用。
    1)Thread类创建的是一个专用线程,建立一个专用线程是非常耗用系统的资源,建议是使用线程池中的线程。
    2)Thread类不能很好的和调用线程进行交互,当任务完成时不能及时的通知,在调用线程也不能随时的取消正在进行的任务。
    另外在以下情况下,就只能选择使用Thread类了。
    1)执行任务的线程要以非普通的优先级去执行,因为线程池的线程都是以普通优先级运行的。
    2)执行任务的线程要表现为一个前台线程,因为线程池的线程始终都是一个后台线程。
    3)异步执行的任务需要长时间的,那么就可以使用Thread类为该任务建立一个专用线程。

    Task类

    public partial class Form1 : Form
        {
            private readonly TaskScheduler contextTaskScheduler;//声明一个任务调度器
            public Form1()
            {
                InitializeComponent();
                contextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();//no.1获得一个上下文任务调度器
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Task<int> t = new Task<int>((n) => Sum((int)n),100);
                t.Start();
                t.ContinueWith(task =>this.textBox1 .Text =task.Result.ToString(),contextTaskScheduler);//当任务执行完之后执行
                t.ContinueWith(task=>MessageBox .Show ("任务出现异常"),CancellationToken.None ,TaskContinuationOptions.OnlyOnFaulted,contextTaskScheduler );//当任务出现异常时才执行
            }
            int Sum(int count)
            {
                int sum = 0;
                for (int i = 0; i < count; i++)
                {
                    Thread.Sleep(10);
                    sum += i;
                }
                Console.WriteLine("任务处理完成");
                return sum;
            }
        }

    这是一个比较完整的Task应用例子。详情可以阅读摘抄的博客原文。

    博客:Winform实现多线程异步更新UI(进度及状态信息)

    有个完整的使用多线程的例子。代码比较复杂。

     ------------------------------

    20190907更新

    文章:C#异步的世界【上】

    写了早期C#中实现异步的方法。

     文章:C#异步的世界【下】

    和上篇配合看

     
     
  • 相关阅读:
    kafka管理器kafka-manager部署安装
    kafka消息监控-KafkaOffsetMonitor
    在Kafka中修改Topic的preferred replica
    kafka中对一个topic增加replicas
    在kafka上对topic新增partition
    kafka log4j配置
    kafka安装与使用
    kafka 消息服务
    软件工程期末考试复习(一)
    PM2自动发布本地项目到服务器
  • 原文地址:https://www.cnblogs.com/Tpf386/p/9951115.html
Copyright © 2020-2023  润新知