2

I am writing a method (in C#) that will be linked to a button in a GUI. One operation in this method is very time intensive (takes several minutes). It's a call to a normal synchronous void function which a cannot edit. In order to make the GUI responsive while the method is executed I tried to use async code:

The time intensive method:

public void TimeIntensiveFunction(string Parameter_1, DataTable Parameter_2, DataTable Parameter_3)
{
     //time intensive stuff
     //creates a large CSV btw.
}         

This is what I came up with:

public async void ResponseToButton_Click(object sender, RoutedEventArgs e)
{
     //doing some stuff
     await AsyncTask_(dt, dt_2);

}

private async System.Threading.Tasks.Task AsyncTask_(DataTable dt, DataTable dt_2)
{
     await System.Threading.Tasks.Task.Run(() => TimeIntensiveFunction(globalText, dt,dt_2));
}

I found a similar problem with this solution Wrapping synchronous code into asynchronous call, but when i run the code an exception is thrown that i dont understand:

System.InvalidOperationException
Nachricht = Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da sich das Objekt im Besitz eines anderen Threads befindet.

english:
System.InvalidOperationException
Nachricht = The calling thread cannot access this object because the object is owned by another thread.

is there a way someone can show me around this exception? The time intensive method is used by other methods in the code but should not be excecuted at the same time. Unfortunately I cannot show you the method itself. Or is there maybe another way to asynchronise my ResponseToButton_Clicke method, so that the GUI will still be responsive?

Thanks for your help!

IcesHay
  • 359
  • 2
  • 13
Leonidas
  • 21
  • 1
  • 2
    Does this answer your question? [The calling thread cannot access this object because a different thread owns it](https://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it) – dymanoid Dec 17 '19 at 14:14
  • 3
    my guess is that you're trying to interact with the GUI in your `TimeIntensiveFunction` - that will not work without some form of thread synchronization. In WinForms, you could achieve that e.g. with [`Control.Invoke`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.invoke?view=netframework-4.8) – germi Dec 17 '19 at 14:25
  • 1
    Hello! Welcome to the community! My advice is: Background processes. In fact, time consuming tasks should not only be done in background tasks but, if possible, in entirely different processes. If you're dealing with a SaaS solution, the best approach would be: Enqueue the task into a Queue and let consumers do the task. The GUI should just monitor the state of the task and give feedback when it is ready. As the comment above said: You're trying to change something on the UI outside the main thread. Good luck! – Eduardo Elias Saléh Dec 17 '19 at 14:26
  • I don't know C# so maybe this is a stupid question, but if you want to asynchronously call some synchronous method, S(), then why can't you write an asynchronous method A() that calls S(), and then write your call to A() ? – Solomon Slow Dec 17 '19 at 15:31
  • Thanks for your comments! @germi I tried to get passt the error by using Control.Invoke(), but apperently i have yet not really understood how to use Control.Invoke() in this situation. Can you show me how you would insert it into my code, please? – Leonidas Dec 17 '19 at 17:13
  • There are multiple questions here on SO that talk about `Control.Invoke`, did you see these: [1](https://stackoverflow.com/questions/6650691/invoke-in-windows-forms), [2](https://stackoverflow.com/questions/2562946/cross-thread-winforms-control-editing), [3](https://stackoverflow.com/questions/4302089/c-sharp-invoke-control-from-different-thread)? These should get you started. If it's still not clear to you, maybe you can ask a new question specifically on how to use it in your case. – germi Dec 17 '19 at 17:35
  • Following @germi, also look at `Control.InvokeRequired` and realize that a Windows Forms `Form` instance is a `Control` (i.e., `Form` (from which you Form class inherits) is a sub-class of `Control`) – Flydog57 Dec 17 '19 at 23:03
  • @Leonidas is it WPF/UWP or WinForms application? – Gleb Dec 18 '19 at 13:53

0 Answers0