0

我正在尝试在我的应用程序中实现异步等待,但遇到了一些困难

在看起来很容易但它并不像这样工作。我有下面的代码,通过等待 LoadAsync 将执行 WCF 服务调用并返回数据,然后我可以加载任务表单。但是,通过 await 调用,我在 Tasks 表单的实例化上得到了一个跨 ui 线程异常。如果我删除 await 那么它可以工作。我究竟做错了什么?

if (!Core.Tasks.IsLoaded)
{
await Core.Tasks.LoadAsync();
}
Core.ShowWait("Opening Tasks");
TasksForm frm = new TasksForm() { MdiParent = Core.MainMDIWindow, CurrentViewName = Core.CurrentUser.UserProfile.TasksLastViewName }; // <-- error on this line

LoadAsync 方法是:

public override Task LoadAsync(bool includeDeleted = false)
{
    return Task.Run(async () =>
    {
        Core.Logger.EnterMethod("_TasksData.Load");
        try
        {
            DataSet = Core.LogbookProData.Tasks.GetTasks(DataUserID, includeDeleted);
            LoadCompleted();
            dsTasks cacheData = await Cache.LoadAsync(ConvertTimeZone);
            if (cacheData != null)
                MergeDataSets(DataSet, cacheData);

            InitializeLayouts();
        }
        catch (Exception ex)
        {
            Core.Logger.LogException("_TasksData.Load", ex);
        }
        finally
        {
            Core.Logger.LeaveMethod("_TasksData.Load");
        }
    });
}
4

1 回答 1

2

您不能从后台线程访问任何 UI 对象。Task.Run在后台线程上执行其委托,因此如果Task.Run委托中有任何访问 UI 的内容(例如,InitializeLayouts听起来很可疑),那么您将收到这样的异常。

Task.Run只有当你有一个 CPU-bound 操作,或者如果你只有一个阻塞 API应该是一个异步调用时,才应该真正使用它。它通常不用于实现async方法。您可能会发现我的async/await介绍帖子很有帮助

例如,如果GetTasks并且MergeDataSets不要阻塞太久,您可以这样实现LoadAsync

public override async Task LoadAsync(bool includeDeleted = false)
{
    Core.Logger.EnterMethod("_TasksData.Load");
    try
    {
        DataSet = Core.LogbookProData.Tasks.GetTasks(DataUserID, includeDeleted);
        LoadCompleted();
        dsTasks cacheData = await Cache.LoadAsync(ConvertTimeZone);
        if (cacheData != null)
            MergeDataSets(DataSet, cacheData);

        InitializeLayouts();
    }
    catch (Exception ex)
    {
        Core.Logger.LogException("_TasksData.Load", ex);
    }
    finally
    {
        Core.Logger.LeaveMethod("_TasksData.Load");
    }
}
于 2013-06-02T00:51:48.920 回答