C#async/await的简易理解,与Task.Run的区别与优势

async:
1、标记一个方法为一异步法,可能会异步执行(没await就是普通方法)
2、该方法可被await

await:
1、await只能在async方法内使用
2、程序遇到第一个await时,会开启一个新线程执行await下方的代码(包括await这行)

async、await演示代码

        public static void Main() {
            Task<int> t = 方法1();
            //非async方法想等待async方法的结束,可使用.Result
            int num = t.Result;//等待方法1执行结束
            Console.ReadLine();
        }
        public static async Task<int> 方法1() {
            //遇到第一个await,函数直接返回,下面的代码(包括await这行)在新线程中执行
            await 方法2();
            //包括上面的await,await会等待async方法的执行结束
            //如果这里去掉这个await,就会直接返回0,而不是等方法3执行结束再返回0
            await 方法3();
            return 0;
        }
        public static async Task<int> 方法2() {
            return await Task.Run(() => {
                Thread.Sleep(1000);
                return 1;
            });
        }
        public static async Task<int> 方法3() {
            await Task.Delay(500);
            return 0;
        }

看上去与Task.Run()区别不大,但是async/await还是有其独特的优势存在
明显的优势:代码简洁,操作便利,如果用Task.Run()写,一堆的(){},可读性大大降低。

async优势之——优雅的异步更新UI线程

1、非常优雅的实现异步更新UI界面,无需使用Invoke,不会阻塞主线程,这点Task.Run做不到。
2、但是要注意死锁问题
(await会获取当前UI线程的SychronizationContext)。
3、注意await之前都还是同步
4、并且由于异步更新线程,使用链式逻辑的时候就要小心了
(比如调用下面代码后去获取textBox数据,textBox要1秒后才会被更新数据)

private async void button1_Click(object sender, EventArgs e) {
    textBox1.Text = await Task.Run(() => {//不阻塞主线程更新textBox
        Thread.Sleep(1000);
        return "测试";
    });
}

async优势之——不妨碍主线程的异步线程阻塞

不会影响到主线程,Thread.Sleep会阻塞主线程,Task.Delay是可以取消的

private async void button1_Click(object sender, EventArgs e) {
	await Task.Delay(2000);//不会阻塞UI线程
	//Thread.Sleep(2000);//会阻塞UI线程
	textBox1.Text = await Task.Run(() => {
		Thread.Sleep(1000);
		return "测试";
	});
}

实用链接:
使用await Task.Delay()实现异步等待
小心async/await模式造成的死锁以及解决办法

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,async/await是一种用于处理异步操作的关键字组合。它可以使代码更加简洁和易于理解,同时也提供了更好的性能和可维护性。 下面是一些C# async/await的复杂运用场景: 1. 并行执行多个异步任务:使用Task.WhenAll方法可以并行执行多个异步任务,并等待它们全部完成。例如: ```csharp public async Task DoMultipleTasksAsync() { Task task1 = Task.Run(() => DoTask1()); Task task2 = Task.Run(() => DoTask2()); Task task3 = Task.Run(() => DoTask3()); await Task.WhenAll(task1, task2, task3); } ``` 2. 异步任务的超时处理:使用Task.Delay和CancellationToken实现异步任务的超时处理。例如: ```csharp public async Task DoTaskWithTimeoutAsync() { var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(5)); try { await Task.Delay(TimeSpan.FromSeconds(10), cts.Token); // 执行异步任务 } catch (OperationCanceledException) { // 超时处理逻辑 } } ``` 3. 异步任务的重试机制:使用循环和延迟重试策略来实现异步任务的重试。例如: ```csharp public async Task DoTaskWithRetryAsync() { int maxRetries = 3; int retryDelaySeconds = 5; for (int retryCount = 0; retryCount < maxRetries; retryCount++) { try { // 执行异步任务 await DoTaskAsync(); return; } catch (Exception) { // 异常处理逻辑 } await Task.Delay(TimeSpan.FromSeconds(retryDelaySeconds)); } // 重试次数超过限制的处理逻辑 } ``` 这些是C# async/await的一些复杂运用场景,希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值