首页 新闻 会员 周边 捐助

关于C#异步编程,在异步方法中给控件赋值不需要invoke吗?

0
悬赏园豆:20 [已解决问题] 解决于 2024-11-12 15:14

····

    private async Task SumPageSizesAsync()
    {
        // Make a list of web addresses.
        List<string> urlList = SetUpURLList();

        var total = 0;

        foreach (var url in urlList)
        {
            byte[] urlContents = await GetURLContentsAsync(url);
            DisplayResults(url, urlContents);
            total += urlContents.Length;
        }
        // Display the total count for all of the websites.
        resultsTextBox.Text +=
            $"\r\n\r\nTotal bytes returned:  {total}\r\n";
    }

····

这是我在msdn上看到的例子

按道理来说 执行byte[] urlContents = await GetURLContentsAsync(url)时就会回到SumPageSizesAsync调用方继续执行主线程,GetURLContentsAsync会放到一个线程中执行,执行完毕该线程会继续执行下面的 resultsTextBox.Text +=....,那么这个线程不是主线程为什么可以直接给控件赋值呢?

猝不及防的主页 猝不及防 | 老鸟四级 | 园豆:2878
提问于:2019-12-09 11:38
< >
分享
最佳答案
0

在默认情况下,一个async方法在调用完成await之后,在原本的线程上继续执行代码,如果是UI线程,那就继续在UI线程上执行。
可以调用ConfigureAwait方法修改这个默认行为,就像这样
await Task.Delay(1000).ConfigureAwait(false);
this.Text = "123";
就会报一个线程间操作无效的异常出来

收获园豆:5
拓拓 | 小虾三级 |园豆:1055 | 2019-12-09 13:20
其他回答(3)
0

xamarin form 都是这么干的,不必惊慌。没有看到源码实现,有两种可能性:

1在此视图模型中,为事件函数做了区别处理;

2在视图中允许了并发访问,这种可能性较小,毕竟不是游戏动画模式,一般人机交互的视图不会这么干;

收获园豆:5
花飘水流兮 | 园豆:13615 (专家六级) | 2019-12-09 12:20
0

你可以打印输出一下await前后的线程信息看看,后面的是代码已经回到UI线程了。

收获园豆:5
Timetombs | 园豆:3959 (老鸟四级) | 2019-12-09 12:26
0

你后半段的理解是错的。

GetURLContentsAsync是在一个线程池线程中执行,执行完毕后就回到原来的线程中了(调用SumPageSizesAsync方法的线程),不是继续用线程池线程执行的。

收获园豆:5
左眼水星 | 园豆:123 (初学一级) | 2019-12-10 11:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册