首页 新闻 搜索 专区 学院

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

0
悬赏园豆:20 [待解决问题]

····

    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 +=....,那么这个线程不是主线程为什么可以直接给控件赋值呢?

猝不及防的主页 猝不及防 | 老鸟四级 | 园豆:2495
提问于:2019-12-09 11:38
< >
分享
所有回答(4)
0

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

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

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

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

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

blackheart | 园豆:3754 (老鸟四级) | 2019-12-09 12:26
0

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

拓拓 | 园豆:1038 (小虾三级) | 2019-12-09 13:20
0

你后半段的理解是错的。

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

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