3

在此处输入图像描述我正在使用 SAP .NET 连接器 3.0 并尝试使用单独的线程登录,这样我就可以让 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?

编辑1:抱歉忘了解释是什么GetData()GetData()在 SAP 中运行各种报告(大量代码)。从视觉上看,我知道它什么时候在那里,因为我的小登录动画将从“登录”变为“抓取数据”。当我看到 UI 挂起时,我看到它是在“登录”阶段。登录动画有一个简单的圆圈旋转。这会在登录中途停止,然后在大约 5 秒后继续。

编辑 2: 悬挂似乎发生在这条线上

SapRfcDestination = RfcDestinationManager.GetDestination(MyServer);

编辑 3:在我看到 UI 挂起的地方暂停应用程序时添加了线程的照片。

4

1 回答 1

2

据推测,内部GetData或内部的Task.Runlambda都没有SAPLogin尝试使用Dispatcher.Invoke,Dispatcher.BeginInvoke或回调 UI 线程Dispatcher.InvokeAsync。首先检查这种可能性。

然后,尝试更改您的代码,如下所示。请注意如何Task.Factory.StartNew使用 withTaskCreationOptions.LongRunning而不是Task.Run以及如何GetData卸载(尽管它已经是async,所以请注意.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);
}
于 2014-02-15T00:35:48.153 回答