····
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 +=....,那么这个线程不是主线程为什么可以直接给控件赋值呢?
在默认情况下,一个async方法在调用完成await之后,在原本的线程上继续执行代码,如果是UI线程,那就继续在UI线程上执行。
可以调用ConfigureAwait方法修改这个默认行为,就像这样
await Task.Delay(1000).ConfigureAwait(false);
this.Text = "123";
就会报一个线程间操作无效的异常出来
xamarin form 都是这么干的,不必惊慌。没有看到源码实现,有两种可能性:
1在此视图模型中,为事件函数做了区别处理;
2在视图中允许了并发访问,这种可能性较小,毕竟不是游戏动画模式,一般人机交互的视图不会这么干;
你可以打印输出一下await前后的线程信息看看,后面的是代码已经回到UI线程了。
你后半段的理解是错的。
GetURLContentsAsync是在一个线程池线程中执行,执行完毕后就回到原来的线程中了(调用SumPageSizesAsync方法的线程),不是继续用线程池线程执行的。