如何等待在主线程上启动的任务

问题描述

在主线程上链接任务和执行任务时,有些事情我无法理解。

当我的模型更新时,我需要链接2个任务:(1)然后更新(2)检查状态。 所以我用continueWith来实现这个目的:

// Update the model
Debug.WriteLine($"BaseModel<{typeof(T)}> - Launching Update Process");
Status = ModelStatus.Updating;
Task Update = Task.Run(() => UpdateDataSpeciliazed());
Debug.WriteLine($"BaseModel<{typeof(T)}> - Update Process Lauchned");

// And check if the status of the model is updated
Update.ContinueWith(antecedent =>
{
    lock (IsLocked)
    {
        Debug.WriteLine($"BaseModel<{typeof(T)}> - Checking ModelStatus ({Status})");

        // UpdateDataSpeciliazed must update the status accordingly
        if (Status == ModelStatus.Updating)
        {
            Debug.WriteLine($"BaseModel<{typeof(T)}> - UpdateDataAsync - ModelStatus not updated");
            throw new NotImplementedException();
        }

        Debug.WriteLine($"BaseModel<{typeof(T)}> - ModelStatus Checked");
    }
});

当派生类的函数UpdateDataSpeciliazed很简单(无子任务)时,该过程的行为与预期的一样。但是,当UpdateDataSpeciliazed在主线程上启动某些操作(如下所示)时,即使我要求等待它们,ContinueWith也不要等到这些操作完成。请参见下面的执行顺序。

protected override async void UpdateDataSpeciliazed()
{
    _Data.Clear();
    Debug.WriteLine($"DaysPrestasService - UpdateDataSpeciliazed");

    await Device.InvokeOnMainThreadAsync(() => {
        Debug.WriteLine($"DaysPrestasService - Transferd to UI Thread");

        // Read and add DATA here

        Status = ModelStatus.Filled;
        Debug.WriteLine($"DaysPrestasService - Endof UI Thread");
    });

    Debug.WriteLine($"DaysPrestasService - UpdateDataSpeciliazed ended");
}

BaseModel -启动异步更新
BaseModel -启动更新过程
BaseModel -更新过程Lauchned
BaseModel -启动错误检查设置
DaysPrestasService-UpdateDataSpeciliazed
BaseModel -检查ModelStatus(更新)
BaseModel -UpdateDataAsync- ModelStatus未更新
DaysPrestasService-转移到UI线程--->完成后检查吗?!?
DaysPrestasService-UI线程结束--->完成检查后完成吗?!?
DaysPrestasService-UpdateDataSpeciliazed已结束--->完成后检查吗?!?

有人能告诉我在ContinueWith中执行跳转到另一个线程时如何防止UpdateDataSpeciliazed开始吗?对我来说很奇怪,因为await之前的Device.InvokeOnMainThreadAsync

非常感谢!

解决方法

那是因为async void不能等待,但是如果可以等待,那么您就不在等待它。因此,继续在方法退出之前运行。

您可以尝试通过异步同步调用来更新用户界面:

protected override void UpdateDataSpeciliazed()
{
    _Data.Clear();
    Debug.WriteLine($"DaysPrestasService - UpdateDataSpeciliazed");

    Device.InvokeOnMainThreadAsync(() => {
        Debug.WriteLine($"DaysPrestasService - Transferd to UI Thread");

        // Read and add DATA here

        Status = ModelStatus.Filled;
        Debug.WriteLine($"DaysPrestasService - Endof UI Thread");
    }).Wait();

    Debug.WriteLine($"DaysPrestasService - UpdateDataSpeciliazed ended");
}

只有在方法完成后,继续才能起作用。

或者作为替代方式:您是否可以将UpdateDataSpeciliazed()的签名更改为async Task