2013-06-02 2 views
0

Я пытаюсь реализовать асинхр ждать в моем приложении, и я бегу в некоторые трудностиCross UI поток недопустимая операция с асинхронным ждут

в том, что выглядит легко, но это не работает, как таковой. У меня есть код, ниже которого я мог бы ожидать, что LoadAsync выполнит вызов службы WCF и вернет данные, после чего я смогу загрузить форму «Задачи». Однако с вызовом wait я получаю исключение перекрестного ui потока при инстанцировании формы Задачи. Если я уйду, то он будет работать. Что я делаю не так?

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"); 
     } 
    }); 
} 

ответ

2

Вы не можете получить доступ к любым объектам пользовательского интерфейса от фонового потока. Task.Run выполняет свой делегат в фоновом потоке, поэтому, если в делегате Task.Run есть что-то, что обращается к пользовательскому интерфейсу (например, InitializeLayouts звуков), вы получите такое же исключение.

Task.Run должны действительно быть использованы только при наличии работы процессора переплете, или если у вас есть только блокирующий API для того, что Шоуде быть асинхронный вызов. Это не обычно используется для реализации async методов. Вы можете найти мой async/await intro post helpful.

Например, если 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"); 
    } 
} 
+0

Thx - Я попытался удалить Task.Run, но это не имело никакого значения. Очень грубая ошибка, чтобы грустно отследить. – Neal

+0

Посмотрите на трассировку стека для исключения. Это должно дать вам хорошую отправную точку. –