How to update WPF control MainWindow

How to update label1 text in code below? I get the message "The calling thread cannot access this object because another thread owns it." I read that others used Dispatcher.BeginInvoke, but I don't know how to implement it in my code.

public partial class MainWindow : Window { System.Timers.Timer timer; [DllImport("user32.dll")] public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii); public struct tagLASTINPUTINFO { public uint cbSize; public Int32 dwTime; } public MainWindow() { InitializeComponent(); StartTimer(); //webb1.Navigate("http://yahoo.com"); } private void StartTimer() { timer = new System.Timers.Timer(); timer.Interval = 100; timer.Elapsed += timer_Elapsed; timer.Start(); } void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO(); Int32 IdleTime; LastInput.cbSize = (uint)Marshal.SizeOf(LastInput); LastInput.dwTime = 0; if (GetLastInputInfo(ref LastInput)) { IdleTime = System.Environment.TickCount - LastInput.dwTime; string s = IdleTime.ToString(); label1.Content = s; } } } 
+4
source share
3 answers

You can try something like this:

 if (GetLastInputInfo(ref LastInput)) { IdleTime = System.Environment.TickCount - LastInput.dwTime; string s = IdleTime.ToString(); Dispatcher.BeginInvoke(new Action(() => { label1.Content = s; })); } 

Read more about Dispatcher.BeginInvoke here

+6
source

You need to save Dispatcher.CurrentDispatcher from the main thread:

 public partial class MainWindow : Window { //... public static Dispatcher dispatcher = Dispatcher.CurrentDispatcher; //... } 

Then, when you need to do something in the context of the main thread, follow these steps:

 MainWindow.dispatcher.Invoke(() => { label1.Content = s; }); 

Note. Dispatcher.BeginInvoke does this asynchronously, unlike Dispatcher.Invoke . You probably need a synchronous call . In this case, the asynchronous call looks fine, but often you may need to update the user interface on the main end, and then continue the current thread, knowing that the update is complete.

Here's a similar question with a complete example.

+2
source

There are two ways to solve this problem:

First, you can use the DispatcherTimer class instead of the Timer class, as shown in this MSDN article , which modifies user interface elements in the Elapsed event in the dispatcher thread.

Secondly, with the existing Timer class, you can use the Dispatcher.BegineInvoke() method according to the code below in the timer_Elapsed event:

 label1.Dispatcher.BeginInvoke( System.Windows.Threading.DispatcherPriority.Normal, new Action( delegate() { label1.Content = s; } )); 
+1
source

Source: https://habr.com/ru/post/1497440/


All Articles