0

내 응용 프로그램에 비동기를 구현하려고하는데 약간의 어려움이 있습니다.

쉽게 보이지만 아직 그렇게 작동하지 않습니다. 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");
        }
    });
}

1 답변


2

백그라운드 스레드에서 UI 개체에 액세스 할 수 없습니다.Task.Run배경 스레드에서 대리자를 실행하므로Task.RunUI에 액세스하는 위임자 (예 :InitializeLayouts소리가 의심 스러울 때), 다음과 같은 예외가 발생합니다.

Task.RunCPU 바운드 조작이있는 경우, 또는 무엇을위한 블로킹 API만을 가지고있는 경우에만 사용해야합니다.큰 소리로 말하다비동기 호출이되어야합니다. 그렇지 않다.정상적으로구현에 사용async행동 양식. 너는 내async/await소개 소개.

예를 들어, ifGetTasksMergeDataSets너무 오래 차단하지 마십시오. 구현할 수 있습니다.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");
    }
}


  • Thx - Task.Run을 제거하려고했지만 아무런 효과가 없습니다. 슬프게도 추적하기 어려운 버그. - Neal
  • 예외에 대한 스택 추적을 살펴보십시오. 그것은 당신에게 좋은 출발점을 제공해야합니다. - Stephen Cleary

관련된 질문

최근 질문