This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 2 years ago.
I'm a beginner with C# so maybe I don't really understand why I have this error.
System.InvalidOperationException: Cross-thread operation not valid:
Control 'lstb_files_r' accessed from a thread other than the thread it
was created on.
This is what I'm doing:
I drop X csv.
I read the first one (lstb_files_r.SelectedIndex = i;)
after finishing I would like to read the 2nd (i++). But I have this error...
Can someone explain to me how can I solve that please ?
When I asked my question I continued to look all the links and I've found something (maybe it's not the best way but I will find an other solution)
I use delegate
lstb_files_r.Invoke((MethodInvoker)delegate
I put all the code inside and it works.
You are performing the cross threaded opertaion which means you are in one thread (which is your algorithm) and want to perform something in another thread (here GUI is another thread) which is not allowed. For that you have to call GUI thread and perform the function. In C# the easiest way is to use backgraoudworker Use of backgroudworker can see here how to use background worker.
In backgroundworker use progressreport to perform the GUI operations. If you need further help I can help you.
Related
This question already has answers here:
Detecting whether on UI thread in WPF and Winforms
(12 answers)
Closed 4 years ago.
The title says it all. I would like to be able to simply detect if work is being executed on the UI thread. Also, if the method is not running on the UI/main thread, can I determine what other thread that it might be? I would like to use this information for debugging purposes. Thanks!
In a UWP app, you can check and store the value of the Environment.CurrentManagedThreadId property when your app starts and then compare the current value of the same property with the stored value to determine whether you are on the same thread.
Or use the CoreDispatcher.HasThreadAccess property to determine whether the current thread can safely update the UI.
This question already has answers here:
How do I update the GUI from another thread?
(47 answers)
Closed 6 years ago.
Simple question, I had an application in console mode. Every thing would write in the console using Console.WriteLine. However, now I have a form and a listbox. I know easily how to do it, however, what is the proper way to do it?
You can access the UI from another thread using delegate, simple and neat:
this.Invoke((MethodInvoker)delegate
{
textBox1.Value = "your text";
});
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
just a simple question on data updating.
Suppose I have a TextBox called txtBox1 and I want to update the value of a string variable called foo.
Which gives the best performance and best to do?
// The lengthier code but will check if the value is the same before updating.
if (foo != txtBox1.Text)
foo = txtBox1.Text;
or
// The shorter code but will update it regardless if it's the same value
foo = txtBox1.Text;
It really depends on what you do with foo variable.
If updating foo involves updating other parts of your application (via data binding for example) then yes, you should only update it when necessary.
Original Answer
Warning: I messed up... this answer applies for the opposite case, that is:
txtBox1.Text = foo
It may depend on what TextBox you are using...
I haven't reviewed all the clases with that name in the .NET framework from Microsoft. But I can tell for System.Windows.Forms.TextBox that the check is done internally, so doing it yourself is a waste. This is probably the case for the others.
New Answer
Note: This is an edit based on the comments. It it taken from granted that the objective is keep track of the modifications of the texbox and that we are working in windows forms or similar dektop forms solution (that may be WinForms, WPF, GTK#, etc..).
IF you need every value...
TextChanged is the way to go if you want a a log or undo feature where you want to offer each value the textbox was in.
Although take note that the event runs in the same thread as that the text was assigned, and that thread ought to be the thread that created the textbox. Meaning that if you cause any kind of lock or do an expensive operation, it will heavily^1 impact the performance of the form, causing it to react slowly because the thread that must update the form is busy in the TextChanged handler.
^1: heavily compared to the alternative presented below.
If you need to do an expensive operation, what you should do is add the values to a ConcurrentQueue<T> (or similar). And then you can have an async^2 operation run in the background that takes the values from it and process them. Make sure to add to the queue the necessary parameters^3, that way the expensive operation can happen in the background.
^2: It doesn't need to be using the async keyword, it can be a ThreadPool, a Timer, a dedicated Thread or something like that.
^3: for example the text, and the time in the case of a log. If have to monitor multiple controls you could also consider using a POCO (Plain Old CLR Object) class or struct to store all the status that need to be kept.
IF you can miss some values...
Using the event
Use the event to update a version number instead of reading the value.
That is, you are going to keep two integer variables:
The current version number that you will increment when there were a change. Use Thead.VolatireWrite for this (there is no need for Interlocked)
The last checked version number that you will update when you read the values from the form (this done from an async operation), and that you will use to verify if there has been any updates recently. Use Interlocked.Exchange to update the value and proceed if the old value is different from the readed one.
Note: Test the case of aritmetic overflow and make sure it wraps MaxValue to MinValue. No, it will not happen often, but that's no excuse.
Again, under the idea that it is ok to miss some values... If you are using a dedicated Thread for this, you may want to use a WaitHandle (ManualResetEvent or AutoResetEvent [and preferably it's slim counterparts]) to have the thread sleep when there hasn't been modifications instead of having it nopping (spin waiting). You will then set the WaitHandle in the event.
This question already has answers here:
Why do UI Controls in WPF have Thread Affinity?
(2 answers)
Can you access UI elements from another thread? (get not set)
(4 answers)
Closed 9 years ago.
I am in learning multithreading (and related stuff like concurrency, TPL - in .NET, Windows) and hope that thу answers to this question would significantly reduce the amount of my doubts.
Why WPF UI requires output (from multiple threads) through the Dispatcher while the console does not?
I hope that this explanation will be a little more detailed then the overused and underdefined in MSDN docs phrase that Console class is thread-safe (or better to avoid the use of ambiguous terms at all).
Update:
Thanks to Justin Pihony's comment, sub-question:
Why reading from WPF UI is not possible without a Dispatcher object while Windows Forms permit both reading and writing without Invoke/BeginInvoke?
Why (or how) does reading compromise thread-safedty of WPF UI?
I am trying to disambiguate for me the phrase from Parallel Programming in .NET Framework 4: Getting Started :
"I didn’t have problems with the console application because the
Console class is thread safe. But in WPF, UI components can be safely
accessed only by a dedicated UI thread"
Proposed topics for reading the answers:
Why does Console.ReadKey() block output of Console.WriteLine called in another thread?
Can you access UI elements from another thread? (get not set)
Why do UI Controls in WPF have Thread Affinity?
Calling Console.WriteLine from multiple threads
WPF/WinForm create and use window, which has affinity on single threading.
console don't use window, it just output/reply string.
it's "by design of window development".
This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 9 years ago.
how can I edit the text in a windows form element if the code that is editing the text 'belongs' to a seperate thread from the one that contains the windows form? I get the exception:
Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.
Thank you.
You will need to use Control.Invoke method like this:
textbox1.Invoke((MethodInvoker)(() =>
{
textbox1.Text="some text";
}));
Check this article too: Threading in UIs