내 응용 프로그램에 비동기를 구현하려고하는데 약간의 어려움이 있습니다.
쉽게 보이지만 아직 그렇게 작동하지 않습니다. LoadAsync가 WCF 서비스 호출을 수행하고 데이터를 반환 할 때까지 기다려야 할 코드는 다음과 같이 Tasks 폼을로드 할 수 있습니다. 그러나 await 호출을 사용하여 작업 폼의 인스턴스에 대한 cross-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");
}
});
}
백그라운드 스레드에서 UI 개체에 액세스 할 수 없습니다.Task.Run
배경 스레드에서 대리자를 실행하므로Task.Run
UI에 액세스하는 위임자 (예 :InitializeLayouts
소리가 의심 스러울 때), 다음과 같은 예외가 발생합니다.
Task.Run
CPU 바운드 조작이있는 경우, 또는 무엇을위한 블로킹 API만을 가지고있는 경우에만 사용해야합니다.큰 소리로 말하다비동기 호출이되어야합니다. 그렇지 않다.정상적으로구현에 사용async
행동 양식. 너는 내async
/await
소개 소개.
예를 들어, ifGetTasks
과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");
}
}