C#异步多线程几种实现方式(.NetFramework)

C#异步多线程几种实现方式

异步编程模式

官方说明:https://learn.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/?source=recommendations
.NET 提供了执行异步操作的三种模式:

**(1)**基于任务的异步模式 (TAP) ,该模式使用单一方法表示异步操作的开始和完成。 TAP 是在 .NET Framework 4 中引入的。 这是在 .NET 中进行异步编程的推荐方法。 C# 中的 async 和 await 关键词以及 Visual Basic 中的 Async 和 Await 运算符为 TAP 添加了语言支持。 有关详细信息,请参阅基于任务的异步模式 (TAP)。

**(2)**基于事件的异步模式 (EAP),是提供异步行为的基于事件的旧模型。 这种模式需要后缀为 Async 的方法,以及一个或多个事件、事件处理程序委托类型和 EventArg 派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 建议新开发中不再使用这种模式。 有关详细信息,请参阅基于事件的异步模式 (EAP)。

**(3)**异步编程模型 (APM) 模式(也称为 IAsyncResult 模式),这是使用 IAsyncResult 接口提供异步行为的旧模型。 在这种模式下,同步操作需要 Begin 和 End 方法(例如,BeginWrite 和 EndWrite以实现异步写入操作)。 不建议新的开发使用此模式。 有关详细信息,请参阅异步编程模型 (APM)。

一、利用委托的异步调用实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            //第一种方法 利用委托的异步调用实现
            Console.WriteLine("===开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            //委托方法
            Func<string, string> ff = (a) =>
            {
                Console.WriteLine("当前线程:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
                Thread.Sleep(3000);
                Console.WriteLine("异步调用{0}", a);
                //Thread.CurrentThread.Suspend();
                return a + ":" + a;
            };
            //回调函数
            AsyncCallback asyncCallback = (ir) =>
            {
                string result = ff.EndInvoke(ir);
                Console.WriteLine(result);
            };
            //执行
            Console.WriteLine("委托异步开始==");
            IAsyncResult asyncResult = ff.BeginInvoke("yibu", asyncCallback, null);
            Console.WriteLine("执行完成:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }
}

二、ThreadPool线程池

说明:默认使用线程池技术,但是可用方法比较单一,只有一个QueueUserWorkItem

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            //第二种 利用线程池实现
            Console.WriteLine("===开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            int b = 0;
            try
            {
                ThreadPool.QueueUserWorkItem((a) =>
                {
                    b++;
                    Console.WriteLine("===异步开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
                    Console.WriteLine("1");
                }, b);
            }
            catch (Exception ex)
            {
                Console.WriteLine("出现错误:{0}", ex.Message);
            }
            Console.WriteLine(b);
            Console.WriteLine("执行完成:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }
}

三、利用 Threed类的Start()

说明:默认没有使用线程池技术,需要自己实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            //第三种 利用 Threed.Start()
            Console.WriteLine("===开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            Func<string, string> f = (a) => a + ":" + a;
            Thread thread = new Thread((a) =>
            {
                Console.WriteLine("===异步开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
                Thread.Sleep(3000);
                string str = f("abc");
                Console.WriteLine(str);
            });
            thread.Start();
            Console.WriteLine("执行完成:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }
}

四、Task 类

官方说明:
Task类表示不返回值并且通常以异步方式执行的单个操作。 Task 对象是在 .NET Framework 4 中首次引入的 基于任务的异步模式 的中心组件之一。 由于对象执行的工作 Task 通常在"线程池线程"上异步执行,而不是在主应用程序线程上同步执行,因此可以使用 Status 属性以及 IsCanceled 、 IsCompleted 和 IsFaulted 属性来确定任务的状态。 通常,lambda 表达式用于指定任务要执行的工作。对于返回值的操作,请使用 Task 类。

4.1 Task定义和执行方法不分离
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===Task开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            //定义异步方法
            Task task = new Task(() =>
            {
                Console.WriteLine("===Task的异步线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
                Thread.Sleep(2000);
            });
            //执行,可以先定义以后再执行,
            task.Start();
            Console.WriteLine("===Task结束:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }
}

4.2 Task定义和执行方法分离
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===Task开始:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            //定义异步方法
            Task task = new Task(() =>
            {
                Console.WriteLine("===Task的异步线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
                Thread.Sleep(2000);
            });
            //执行,可以先定义以后再执行,
            task.Start();
            Console.WriteLine("===Task结束:当前线程:{0}===", Thread.CurrentThread.ManagedThreadId.ToString());
            Console.ReadKey();
        }
    }
}

五、async/await 语法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            // 第五种 await 语法
            Console.WriteLine("===");
            doWork();
            Console.WriteLine("===");
            Console.ReadKey();
        }

        public static async Task doWork()
        {
            await Task.Run(() =>
            {
                Console.WriteLine("当前线程:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
            });
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值