C# 高级特性(十一):多线程之async,await

之前使用Thread和Task启动多线程时都会遇到一个麻烦,就是如何反馈结果。在代码里就是如何设计回调函数。如果带界面还得考虑UI线程的问题。

而使用async,await可以达到两个效果。

1 不用设计回调函数,直接按单线程的格式写。

2 不用考虑UI线程问题。

下面用两个例子来说明:

示例1 纯后端代码

使用的示例如下:

 internal class asyncTest
 {
     // 方法1 使用async, await关键字
     public async Task<int> Test1()
     {
         await Task.Delay(1000); // 模拟耗时操作
         return 1;
     }


     // 方法2 使用 task启动线程
     public delegate void LogUpdateHandler(string message);

     public event LogUpdateHandler? LogUpdateEvent;
     public void Test2()
     {
         Task.Run(() =>
         {
             Thread.Sleep(1000);
             LogUpdateEvent?.Invoke("Task: result=2");
         });
     }
 }

调用代码如下:

void Main()
{
	Console.WriteLine("Hello, World!");

	asyncTest test = new asyncTest();

	int result1 = await test.Test1();
    Console.WriteLine("async 、await: result=" + result1.ToString());

	test.LogUpdateEvent += fun;
	test.Test2();

	Console.ReadLine();
}


void fun(string meg) {

    Console.WriteLine(meg);
}

执行结果:

可以看到,效果两种方法是一样的。但是async,await方法要简洁很多,也不用写回调函数。

示例2 带有UI界面:

一样的两个示例方法:

internal class asyncTest
{
    public async Task<int> Test1()
    {
        await Task.Delay(1000); // 模拟耗时操作
        return 1;
    }

    public delegate void LogUpdateHandler(string message);

    public event LogUpdateHandler? LogUpdateEvent;
    public void Test2()
    {
        Task.Run(() =>
        {
            Thread.Sleep(1000);
            LogUpdateEvent?.Invoke("Task: result=2");
        });
    }
}

页面调用示例:

 private async void Button_Click(object sender, RoutedEventArgs e)
 {
     asyncTest test = new asyncTest();

     int result1 = await test.Test1();

     this.listbox01.Items.Add("async 、await: result=" + result1.ToString());

     test.LogUpdateEvent += AsyncTest_LogUpdateEvent;
     test.Test2();
 }

private void AsyncTest_LogUpdateEvent(string message)
{
    // 使用 Dispatcher.Invoke 在 UI 线程上更新页面控件
    Dispatcher.Invoke(() =>
    {
        this.listbox01.Items.Add(message);
    });           
}

结果:

同样,async,await方法要简洁很多,并且直接调用UI控件。

而task方法,还得通过 Dispatcher.Invoke 来调用UI控件。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值