Task.Run然后使用async await ContinueWith调用主线程替代?

Noo*_*001 3 c# multithreading asynchronous xamarin.forms

以下代码完美无缺.它显示UI上的微调器,使用线程池中的线程启动任务并运行繁重的操作,一旦完成,隐藏微调器的逻辑就会按预期在主线程上执行.

    public void LoadCustomers()
    {
        // Update UI to show spinner
        this.LoadingCustomers = true;

        Task.Run(async () =>            
        {
            var customers = await this.custService.GetCustomers();
            // code truncated for clarity

            Device.BeginInvokeOnMainThread(() => 
            {
                // Update UI to hide spinner
                this.LoadingCustomers = false;
            });
        });
    }
Run Code Online (Sandbox Code Playgroud)

我的问题; 有没有更好的方法使用ContinueWith/ConfigureAwait选项编写此逻辑?使用这些选项似乎阻止了UI线程.在下面的示例中,UI线程是否应该继续运行UI逻辑(为微调器/用户输入设置动画),然后返回以完成ContinueWith内部的逻辑?

    public void LoadCustomers()
    {
        // Update UI to show spinner
        this.LoadingCustomers = true;

        this.custService.GetCustomers().ContinueWith((t) =>
        {
            var customers = t.Result;
            // code truncated for clarity

            // Update UI to hide spinner
            this.LoadingCustomers = false;
        });
    }
Run Code Online (Sandbox Code Playgroud)

根据评论中的要求,以下是GetCustomers的代码.dbContext是EntityFrameworkCore.

    public async Task<List<CustomerModel>> GetCustomers()
    {
        return await this.dbContext.Customers.ToListAsync();
    }
Run Code Online (Sandbox Code Playgroud)

UPDATE

但是,FCin的答案是正确的; 这个的原因根似乎是EFCore和ToListAsync,它不是异步运行的.

FCi*_*Cin 7

编写这种方法的正确方法是async/await从头到尾使用.现在你正在做火并忘记意义,如果内部有例外,Task.Run你永远不会知道它.您应该从事件处理程序开始.这可以是任何东西,鼠标点击,页面加载等.

private async void MouseEvent_Click(object sender, EventArgs args)
{
    await LoadCustomers();
}

public async Task LoadCustomers()
{
    // Update UI to show spinner
    this.LoadingCustomers = true;

    // We don't need Device.BeginInvokeOnMainThread, because await automatically 
    // goes back to calling thread when it is finished
    var customers = await this.custService.GetCustomers();

    this.LoadingCustomers = false;
}
Run Code Online (Sandbox Code Playgroud)

有一种简单的方法可以记住何时使用Task.Run.使用Task.Run 只有当你做一些CPU的约束,如计算PI的数字.