0

when I execute the following code in my wpf application. I get a System.InvalidOperationException, as soon as the code trys to access textBoxResult.Text. I assume it has something to do with scope. I am not that expierenced with c#. Could someone please explain what is the problem and how to do it right?

Code:

private void buttonRun_Click(object sender, RoutedEventArgs e)
        {
            var startTimeSpan = TimeSpan.Zero;
            var periodTimeSpan = TimeSpan.FromSeconds(5);

            var timer = new System.Threading.Timer((timer_e) =>
            {
                textBoxResult.Text = "";
                device.Service.Inputs = textBoxRun.Text;
                device.Service.Run(device.ResourceStore.Resources);
            }, null, startTimeSpan, periodTimeSpan);

        }
TruckerCat
  • 1,437
  • 2
  • 16
  • 39
  • 1
    Please provide more details on the exception (at least the message). But if it is something like "_The calling thread cannot access this object because a different thread owns it_", see [this question](https://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it). – Grx70 Jan 18 '18 at 11:20
  • @Grx70 Thank you, your link answers my question. Sorry for not providing the message. I did not see it. Otherwise I would have googled the message text. – TruckerCat Jan 18 '18 at 11:24
  • Better use a DispatcherTimer. It already runs in the UI thread. Also make sure you don't start a new timer on each Click. – Clemens Jan 18 '18 at 11:40

1 Answers1

0

What I know so far, you can only access visual elements from UI thread.

Your lambda is running on different thread. You can use the dispatcher, see this answer :)

Accessing UI (Main) Thread safely in WPF

Application.Current.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));

So, in your case something like:

var timer = new System.Threading.Timer((timer_e) =>
{
    Application.Current.Dispatcher.Invoke(new Action(() => {
        textBoxResult.Text = "";
        device.Service.Inputs = textBoxRun.Text;
        device.Service.Run(device.ResourceStore.Resources);
    }
}, null, startTimeSpan, periodTimeSpan);