I am using SAP .NET Connector 3.0 and trying to login on using a separate thread so I can have the UI displaying a kind of login animation.
I am using Async and Await to start the login but the UI hangs for about 10 seconds during login.
Here is the code, its rough because I am quickly drafting a program.
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;
});
}
I can only imagine that something in the Task is using the UI?
EDIT 1:
Sorry forgot to explain what GetData()
does.
GetData()
runs various reports in SAP (lots of code). Visually, I know when its there because my little login animation will change from "Logging In" to "Grabbing Data".
When I see the UI hang I see it is during the "Logging In" phase. The login animation has a simple circle spinning. This stops part way through the login and then continues after about 5 seconds.
EDIT 2: The hanging seems to occour at this line here
SapRfcDestination = RfcDestinationManager.GetDestination(MyServer);
EDIT 3: Added a Photo of the threads when pausing application at the point where I see the UI hang.
Presumably, nothing inside GetData
or the Task.Run
lambda inside SAPLogin
is trying to callback the UI thread with Dispatcher.Invoke
, Dispatcher.BeginInvoke
or Dispatcher.InvokeAsync
. Check for such possibility first.
Then, try changing your code like below. Note how Task.Factory.StartNew
with TaskCreationOptions.LongRunning
is used instead of Task.Run
and how GetData
is offloaded (despite it's already async
, so mind .Unwrap()
here). If that helps, try each change independently, to see which one particularly helped, or whether it was a combination of both.
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);
}