C#实现异步编程的常用方式总结

开发 前端
异步编程是现代软件开发中不可或缺的一部分,尤其是在处理耗时操作时。C#提供了多种实现异步编程的方式,包括使用async和await关键字、Task类、基于委托的异步方法、基于IAsyncEnumerable的异步数据流以及基于TPL Dataflow的异步数据流处理。

异步编程是现代软件开发中不可或缺的一部分,尤其是在处理耗时操作时。C#作为一种功能强大的编程语言,提供了多种实现异步编程的方式。本文将介绍C#中常用的五种异步编程方式,并附上示例代码。

1. 使用async和await关键字

C# 5.0引入了async和await关键字,极大地简化了异步编程。使用async标记的方法可以在不阻塞主线程的情况下执行异步操作,而await关键字则用于等待一个Task完成。

using System;
using System.Threading.Tasks;

public class AsyncExample
{
    public static async Task Main(string[] args)
    {
        Console.WriteLine("调用异步方法前");
        string result = await GetDataAsync("https://example.com/data");
        Console.WriteLine("调用异步方法后");
        Console.WriteLine(result);
    }

    public static async Task<string> GetDataAsync(string url)
    {
        using (HttpClient client = new HttpClient())
        {
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
    }
}

2. 使用Task类

Task类是.NET Framework 4.0引入的,用于表示一个异步操作。Task.Run方法是一个常用的方式来启动一个后台任务。

using System;
using System.Threading.Tasks;

public class TaskExample
{
    public static async Task Main(string[] args)
    {
        Console.WriteLine("主线程,线程ID: " + Thread.CurrentThread.ManagedThreadId);
        Task task1 = new Task(() => TaskFunc1());
        task1.Start();
        
        var result = Task.Run<string>(() => { return TaskFunc2(); });
        Console.WriteLine(result.Result);
    }

    private static void TaskFunc1()
    {
        Console.WriteLine("Task方式一开启的线程ID: " + Thread.CurrentThread.ManagedThreadId);
    }

    private static string TaskFunc2()
    {
        return "Task方式二开启的线程ID: " + Thread.CurrentThread.ManagedThreadId;
    }
}

3. 基于委托的异步方法

在委托类型中定义BeginInvoke()和EndInvoke()两个方法,可以实现异步编程。

using System;
using System.Threading;

public class DelegateAsyncExample
{
    public static void Main(string[] args)
    {
        Console.WriteLine("调用异步方法前");
        string param = "参数";
        PostAsync(param);
        Console.WriteLine("调用异步方法后");
        Console.ReadKey();
    }

    private delegate void AsyncFoo(string param);

    private static void PostAsync(object param)
    {
        AsyncFoo caller = Myfunc;
        caller.BeginInvoke(param.ToString(), FooCallBack, caller);
    }

    private static void FooCallBack(IAsyncResult ar)
    {
        var caller = (AsyncFoo)ar.AsyncState;
        caller.EndInvoke(ar);
    }

    private static void Myfunc(string param)
    {
        Console.WriteLine("通过委托来实现异步编程的");
    }
}

4. 基于IAsyncEnumerable的异步数据流

IAsyncEnumerable是.NET Core 2.0引入的,提供了一种异步枚举大量数据的方式。

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

public class AsyncStreamExample
{
    public static async Task Main(string[] args)
    {
        await foreach (var item in GetLargeDataAsync())
        {
            Console.WriteLine(item);
        }
    }

    public static async IAsyncEnumerable<int> GetLargeDataAsync()
    {
        for (int i = 0; i < 10; i++)
        {
            await Task.Delay(1000); // 模拟异步操作
            yield return i;
        }
    }
}

5. 基于TPL Dataflow的异步数据流处理

TPL Dataflow(Task Parallel Library Dataflow)提供了多种块(如BufferBlock、TransformBlock<T, T>等),可以组合起来构建数据处理管道。

using System;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

public class DataflowExample
{
    public static async Task Main(string[] args)
    {
        var buffer = new BufferBlock<int>();
        var processor = new TransformBlock<int, string>(async x => await ProcessAsync(x));
        buffer.LinkTo(processor);

        buffer.Post(1);
        buffer.Post(2);
        buffer.Complete();

        await processor.Completion;
    }

    private static async Task<string> ProcessAsync(int x)
    {
        await Task.Delay(1000); // 模拟异步操作
        return "Processed: " + x;
    }
}

结论

异步编程是现代软件开发中不可或缺的一部分,尤其是在处理耗时操作时。C#提供了多种实现异步编程的方式,包括使用async和await关键字、Task类、基于委托的异步方法、基于IAsyncEnumerable的异步数据流以及基于TPL Dataflow的异步数据流处理。每种方式都有其适用场景和优势,开发者可以根据项目的具体需求选择合适的方式。

责任编辑:武晓燕 来源: 程序员编程日记
相关推荐

2019-05-16 13:00:18

异步编程JavaScript回调函数

2021-10-12 17:47:22

C# TAP异步

2015-09-16 15:11:58

C#异步编程

2009-09-09 13:31:15

C# TextBox

2009-08-20 17:30:56

C#异步编程模式

2009-08-20 17:47:54

C#异步编程模式

2012-07-27 10:02:39

C#

2022-07-01 08:00:44

异步编程FutureTask

2009-07-31 18:28:46

实现C#显示图像

2009-08-21 09:20:44

C#异步套接字

2009-08-21 10:13:02

C#异步初步

2016-12-14 15:05:08

C#异步编程

2009-08-26 09:48:48

C#异步套接字

2009-08-21 11:24:16

C#异步调用

2009-08-20 16:33:44

Socket异步通讯

2021-08-02 11:13:28

人工智能机器学习技术

2009-08-21 10:17:14

C#异步网络编程

2009-08-25 11:10:20

C#编程实现显示XML

2024-05-11 07:13:33

C#Task编程

2024-06-25 08:33:48

点赞
收藏

51CTO技术栈公众号