UI线程中异步任务续行B2的执行时隙是否可确定?
异步方法执行时序问题
假设Executor()运行在UI线程上。
void Executor() { BadAsync(); Thread.Sleep(1000); // E1 Thread.Sleep(1000); // E2 } async void BadAsync() { await Task.Delay(1000); // B1 Thread.Sleep(1000); // B2 }
- 由于
Executor()未等待BadAsync(),因此B1和E1在第一秒内同时运行。 - 由于
B1捕获了UI线程,因此B2也将在UI线程上运行。 - UI线程中有两个时隙
x和y可供B2和E2使用(原示意图展示了这两个时隙的分布)。
我们能否确定B2会占用哪个时隙?
补充说明
使用MAUI编写的最小示例。
<VerticalStackLayout> <Label x:Name="start" Text="Start"/> <Label x:Name="stop" Text="Stop"/> </VerticalStackLayout>
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); start.Text = DateTime.UtcNow.ToLongTimeString(); } protected override async void OnAppearing() // 类比BadAsync() { var d = 979; // 在我的计算机上,979是临界值的平均值 await Task.Delay(d); Thread.Sleep(5000 - d); stop.Text = DateTime.UtcNow.ToLongTimeString(); } }
// Page.cs [EditorBrowsable(EditorBrowsableState.Never)] public void SendAppearing()// 类比Executor() { // 其他逻辑... OnAppearing(); Appearing?.Invoke(this, EventArgs.Empty); // 其他逻辑... }
- 当
d远小于979时,程序先显示空白窗口,数毫秒后切换为包含start和stop时间的界面。此场景下B2在SendAppearing()内执行(即SendAppearing()返回前)。 - 当
d远大于979时,程序先显示仅包含start时间的界面,数毫秒后切换为同时显示start和stop时间的界面。此场景下B2在SendAppearing()外执行(即SendAppearing()返回后)。
实际业务示例
public partial class MainPage : ContentPage { public MainPage(MainPageViewModel model) { InitializeComponent(); BindingContext = model; } protected override async void OnAppearing() // 类比BadAsync() { if(BindingContext is MainPageViewModel model) { await model.LoadDataAsync(); UpdateUISync(); } } }
内容的提问来源于stack exchange,提问作者D G
相关产品推荐
相关产品推荐

