异步编程学习

 

摘抄自文章:.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#异步的世界【下】

和上篇配合看

 

 

 

 

 
 

 

posted on   荆棘人  阅读(120)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
历史上的今天:
2017-11-13 asp.net提交危险字符处理方法之一

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示