Click here to Skip to main content
15,889,884 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I do something like this to run a python script in a .net environment (works fine):

public partial class MainWindow : Window
{
    private readonly ScriptEngine m_engine;
    private readonly ScriptScope m_scope;

    public MainWindow()
    {
        InitializeComponent();
        m_engine = Python.CreateEngine();
        dynamic scope = m_scope = m_engine.CreateScope();
    }

    public void ExecuteScript()
    {
        try
        {
            m_engine.Execute(textEditor.Text, m_scope);

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

    }
}

It would be nice, if there is a chance to execute the instruction
m_engine.Execute(textEditor.Text, m_scope);
in a background task to not completly block the GUI of the application.

What I have tried:

However, the easy way to put this in a Task like this:
await Task.Run(() => m_engine.Execute(textEditor.Text, m_scope));
does not work. Any ideas on how to get this run?
Thanks Joe

update:
I get the following error message: The calling thread cannot access this object because a different thread owns it.

Update 2:
I understood that I need to put the Execute inbetween a dispatcher invoke:
await Task.Run(() => this.Dispatcher.Invoke(() => m_engine.Execute(textEditor.Text, m_scope)));; 

This works so far but the main thread with the GUI is still blocked as long as the script is being executed. What has to be done, that the thread runs in background and the GUI is still accessible?

Update 3:

These are my methodes:
private void Run(object sender, RoutedEventArgs e)
{            
      ExecuteScriptAsync(textEditor.Text);
}

private async void ExecuteScriptAsync(string script)
{
    await Task.Run(() => m_engine.Execute(script, m_scope)); 
}           

When I just using
await Task.Run(() => m_engine.Execute(script, m_scope));
without dispatcher I still get "The calling thread cannot access this object because a different thread owns it" (even when using a variable instead of the Textbox.Text)
private async void ExecuteScriptAsync(string script)
{
  await Task.Run(() => this.Dispatcher.Invoke(() => m_engine.Execute(script, m_scope).ConfigureAwait(true))); ;
            
}
works without "The calling thread cannot access this object because a different thread owns it". However the UI is blocked as long as the script operates. Question is, how to run the background task without blocking the calling UI task.
Posted
Updated 5-Oct-20 4:13am
v5
Comments
CHill60 5-Oct-20 8:02am    
"does not work" is not a helpful description of your problem. What happens/does not happen?

1 solution

Quote:
The calling thread cannot access this object because a different thread owns it.
You are trying to access a UI control (textEditor) from a background thread.

When you introduce the Dispatcher call, you are pushing the execution back onto the UI thread.

Instead, use a variable to pass the data to the background thread:
C#
string scriptToExecute = textEditor.Text;
await Task.Run(() => m_engine.Execute(scriptToExecute, m_scope));
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900