You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 15:32:08