2014-02-14 11 views
3

enter image description here SAP .NET Connector 3.0을 사용 중이며 별도의 스레드를 사용하여 로그인하려고하므로 UI에 일종의 로그인 애니메이션이 표시 될 수 있습니다.Task.Run과 함께 대기 중이지만 UI가 몇 초 동안 계속 응답합니까?

Async 및 Await을 사용하여 로그인을 시작했지만 로그인 중에 UI가 약 10 초 동안 중단됩니다.

코드는 매우 까다롭기 때문에 프로그램을 빠르게 작성하고 있습니다.

async void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    Busy.Visibility = System.Windows.Visibility.Visible; // Shows progress animation 

    if (await SAPLogin()) // Waits for login to finish, will always be true at the moment 
    { 
     await GetData(); // does things with sap 

     Busy.Visibility = System.Windows.Visibility.Collapsed; // Hides progress animation 
    } 
} 


private Task<bool> SAPLogin() 
{ 
    bool LoggedIn = true; 

    return Task.Run(() => 
     { 
      Backend = new BackendConfig(); 
      RfcDestinationManager.RegisterDestinationConfiguration(Backend); 
      SapRfcDestination = RfcDestinationManager.GetDestination(MyServer); // MyServer is just a string containing sever name 

      SapRap = SapRfcDestination.Repository; 

      BapiMD04 = SapRap.CreateFunction("MD_STOCK_REQUIREMENTS_LIST_API"); 

      BapiMD04.SetValue("WERKS", "140"); 

       return LoggedIn; 
     }); 
}  

나는 작업에서 UI가 뭔가를 사용하고 있다고 상상할 수 있습니까?

EDIT 1 : 무엇이 GetData()을 설명하는지 잊어 버렸습니다. GetData()은 SAP (다양한 코드)에서 다양한 보고서를 실행합니다. 내 작은 로그인 애니메이션이 "로그인"에서 "데이터 가져 오기"로 바뀔 것이기 때문에 시각적으로, 언제 거기에 있는지 알 수 있습니다. UI가 멈 추면 "로그인 중"단계에 있음을 알 수 있습니다. 로그인 애니메이션에는 간단한 원이 회전합니다. 이것은 로그인을 통해 부분적으로 멈추고 약 5 초 후에 계속됩니다.

편집 2 : 거는 여기이 선에서 occour 보인다

SapRfcDestination = RfcDestinationManager.GetDestination(MyServer); 

편집 3 : 추가 나는 UI 요령을 참조 스레드 시점에서 응용 프로그램을 일시 중지의 사진.

+3

'GetData'는 무엇을합니까? – usr

+0

죄송합니다. 모든 사람이 볼 수 있도록 원래 게시물을 편집합니다. – Gaz83

+0

100 % 확신하기 위해 전체'if '를 주석 처리합니다 (나는 그렇지 않다고 생각합니다). 'if (거짓 && SAPLogin()) 대기'. – usr

답변

2

아마도 GetData 내부 또는 아무것도 SAPLogin 내부 Task.Run 람다 Dispatcher.Invoke, Dispatcher.BeginInvoke 또는 Dispatcher.InvokeAsync으로 UI 스레드 콜백을 시도하지 않는다. 그런 가능성을 먼저 확인하십시오.

그런 다음 아래 코드를 변경해보십시오. 대신 Task.Factory.StartNewTaskCreationOptions.LongRunning이 어떻게 사용되는지, 그리고 이미 async인데도 GetData이 오프로드되었으므로 여기에 .Unwrap()을 입력하십시오. 도움이된다면, 각 변경 사항을 개별적으로 시도해보십시오. 특히 어떤 변경 사항이 도움이되었는지, 또는 두 변경 사항의 조합인지 여부를 확인하십시오.

async void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    Busy.Visibility = System.Windows.Visibility.Visible; // Shows progress animation 

    if (await SAPLogin()) // Waits for login to finish, will always be true at the moment 
    { 
     //await GetData(); // does things with sap 
     await Task.Factory.StartNew(() => GetData(), 
      CancellationToken.None, 
      TaskCreationOptions.LongRunning, 
      TaskScheduler.Default).Unwrap(); 

     Busy.Visibility = System.Windows.Visibility.Collapsed; // Hides progress animation 
    } 
} 

private Task<bool> SAPLogin() 
{ 
    bool LoggedIn = true; 

    return Task.Factory.StartNew(() => 
    { 
     Backend = new BackendConfig(); 
     RfcDestinationManager.RegisterDestinationConfiguration(Backend); 
     SapRfcDestination = RfcDestinationManager.GetDestination(MyServer); // MyServer is just a string containing sever name 

     SapRap = SapRfcDestination.Repository; 

     BapiMD04 = SapRap.CreateFunction("MD_STOCK_REQUIREMENTS_LIST_API"); 

     BapiMD04.SetValue("WERKS", "140"); 

     return LoggedIn; 
    }, 
    CancellationToken.None, 
    TaskCreationOptions.LongRunning, 
    TaskScheduler.Default); 
} 
+0

SAPLogin() 메소드를 버전으로 변경하면 문제가 해결되었는지 확인할 수 있습니다. – Gaz83

+0

@ Gaz83, 내 설명은 SAP .NET 커넥터 스레드 풀에서 너무 많은 스레드를 사용합니다. 너무 많은 사람들이 당신을 위해 많이 남지 않았습니다. 실제로 비동기 웹 서비스 호출을 수행해야하는 무언가에 대해 문제가 있습니다. 이를 확인하려면'Process.GetCurrentProcess(). Threads.Count'를 확인하고'ThreadPool.GetMaxThreads'의 결과와 비교하십시오. – Noseratio

+0

이제'SapRap = SapRfcDestination.Repository' 줄 다음에 시도하여 다음 결과를 얻었을 때 올바른 위치에 넣었는지 확실하지 않습니다. Process.GetCurrentProcess(). Threads.Count = 21'을 호출하고 ThreadPool.GetMaxThreads를 호출하면 다음과 같은 2 개의 출력 매개 변수가 설정됩니다. 'WorkerThreads = 1023' 및'CompletionPortThreads = 1000 ' – Gaz83