내 응용 프로그램에 비동기를 구현하려고하는데 약간의 어려움이 있습니다.
쉽게 보이지만 아직 그렇게 작동하지 않습니다. 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.RunUI에 액세스하는 위임자 (예 :InitializeLayouts소리가 의심 스러울 때), 다음과 같은 예외가 발생합니다.
Task.RunCPU 바운드 조작이있는 경우, 또는 무엇을위한 블로킹 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");
}
}