I recently created a form application through the Windows Form Application template in Visual Studio. I think the program was automatically created with multiple threads, putting the UI on one thread and whatever else on the other thread. I didn't put any code in the application to use multithreading.
Regardless I ran into and fixed the error described here. An error was thrown because I accessed a UI object from within the code block below. The issue being that the code was being ran from a different thread than the UI's thread.
What I want to know is the program actually using multiple threads? and if so how do I prevent that from happening. If not, what is happening here?
For reference, the code where I ran into this issue was in the same class that I initialize the form with. The line where I ran into the issue was on the last line in the CheckUp function (which has been altered to allow different thread access).
Note: The code is structured to be moved to a console app, so the timer method and some other stuff is less kosher
public partial class Form : System.Windows.Forms.Form
{
public Form() {
InitializeComponent();
System.Timers.Timer actionTimer = new System.Timers.Timer(1000);
actionTimer.Elapsed += actionTimerTick;
actionTimer.AutoReset = true;
actionTimer.Enabled = true;
}
private void actionTimerTick(object sender, EventArgs e) {
CheckUp();
}
public void CheckUp() {
bool onlineStatus = GetOnlineStatus();
string status = (onlineStatus) ? "Online" : "Offline";
statusOutputLabel.Invoke((Action)(() => statusOutputLabel.Text = status ));
}
private static bool GetOnlineStatus() {
/*unrelated*/
}
}
What I want to know is how to do manipulate the program to run everything on a single thread so that I do not have to worry about adding the extra code to manipulate UI objects,
Easy. Just don't add any explicit create-thread code in your Windows Forms app.
I recently created a form application through the Windows Form Application template in Visual Studio. The program was automatically created with multiple threads, putting the UI on one thread and whatever else on the other thread (I think).
Applications created by the Windows Forms Application template are inherently single-threaded by default so not sure why you think you have additional threads.
If you did create additional worker threads with respect to that other post, then you should use Control.BeginInvoke rather than Control.Invoke since the later can lead to potential thread dead-lock.
Additional
GUI toolkits like WinForms are potentially always single-threaded. For a jolly-good read as to why check out this article.
KGH:
The problem of input event processing is that it tends to run in the opposite direction to most GUI activity. In general, GUI operations start at the top of a stack of library abstractions and go "down". I am operating on an abstract idea in my application that is expressed by some GUI objects, so I start off in my application and call into high-level GUI abstractions, that call into lower level GUI abstractions, that call into the ugly guts of the toolkit, and thence into the OS. In contrast, input events start of at the OS layer and are progressively dispatched "up" the abstraction layers, until they arrive in my application code.
Now, since we are using abstractions, we will naturally be doing locking separately within each abstraction. And unfortunately we have the classic lock ordering nightmare: we have two different kinds of activities going on that want to acquire locks in opposite orders. So deadlock is almost inevitable. Golly, tell me more...
And that's why, like Java AWT, WinForms is also single-threaded.
See also
kgh, "Multithreaded toolkits: A failed dream? Blog", https://community.oracle.com/blogs/kgh/2004/10/19/multithreaded-toolkits-failed-dream, retrieved 2016/7/27
You are using System.Timer. https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx
For winforms apps you are better off using the one for winforms...
https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx
It is designed to support single threaded UIs. :-
A Timer is used to raise an event at user-defined intervals. This Windows timer is designed for a single-threaded environment where UI threads are used to perform processing. It requires that the user code have a UI message pump available and always operate from the same thread, or marshal the call onto another thread.
Related
I've recently encountered a STA-related error in my program when I tried to launch an OpenFileDialog in a WinForm. I've done some reading, and before I add the [STAThread] attribute to my main thread I want to know how it will affect my program's execution.
I am a foreigner to COM so not everything I read made sense to me. Some points that stuck with me are:
The [STAThread] attribute defines the application as using a single-threaded apartment model.
More specifically, it changes the state of the application thread to be single-threaded.
http://www.a2zdotnet.com/View.aspx?Id=93
The STA architecture can impose significant performance penalties when an object is accessed by many threads. Each thread's access to the object is serialized and so each thread must wait in line for its turn to have a go with the object.
http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa
I understand the need for thread-safety but I still don't understand what STAThread does. In my program (which I inherited from another developer) the main thread launches several other threads, one of which initializes the UI forms - and I think this is where the problem arises. With [STAThread] added what happens to the new threads? Does this affect multi-thread communication for non-Windows objects?
The error occurs when I try to open an OpenFileDialog in one of my forms. I added the dialog to the form using the VS designer: it didn't work. I then attempted to create a dialog box in a global file which is run by the main thread and call that instance from my form. It had no effect.
[STAThread] or Thread.SetApartmentState() are a really, really big deal. You make a promise to the operating system that you write code that is well-behaved. It matters to lots and lots of code inside Windows as well as components you use that are not thread-safe. Standard examples of such code are the Clipboard, Drag + Drop, the shell dialogs (like OpenFileDialog), components like WebBrowser and many Windows sub-components that are wrapped by .NET classes.
Thread-safety is always a big deal, writing truly thread-safe code is very, very difficult. The .NET Framework itself accomplishes it very rarely. Very basic classes list List<> are not thread-safe.
By making the promise to behave well, you must abide by the rules of writing code in a thread that reports itself to be an STA thread. You must do two basic things:
You must pump a message loop. Aka Application.Run() in a Winforms or WPF app. A message loop is a basic mechanism by which you can get code to run on a specific thread. It is the universal solution to the producer-consumer problem. Which solves the thread-safety problem, if you call thread-unsafe code always from the same thread then it isn't unsafe anymore.
You must never block your thread. Blocking an STA thread is very likely to cause deadlock. Because it stops those chunks of code that are not thread-safe from being called. There is core support for this in the CLR, blocking an STA thread with WaitOne() causes it to pump a message loop itself.
These requirements are easily met in a Winforms or WPF app. They are class libraries that were completely designed to help you implement them. Almost every single aspect about the way they behave was affected by it.
You must mark the Main() method in a GUI app as [STAThread]. Rock-hard requirement when it creates windows.
Creating another thread that displays a window is supported and possible. This time you must call SetApartmentState() to switch to STA, it cannot be a thread-pool thread. Getting this right is very difficult, in Winforms you'll get bitten badly by the SystemEvents class if you use certain kind of controls. It has a knack to start raising its events on the wrong thread. Debugging such a problem requires black-belt skills that look like this. That's suppose to scare you.
I think my problem is similar to:
.NET 4.0 and the dreaded OnUserPreferenceChanged Hang
I have also looked through:
http://ikriv.com/en/prog/info/dotnet/MysteriousHang.html#BeginInvokeDance
I have removed our splash screen.
I also tried adding the suggested code: Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { }; to our main() method.
I'm looking for some ideas and information on how to troubleshoot.
For our main() method we start a windowmanager class which is a form using Application.Run
It is just an icon in the task tray ( we don't show a window).
Whenever we launch an object we have a background thread which creates a form and then does Application.Run( form )
At the time of Application.Run( form ) form.IsHandleCreated = false.
I use the freezer application from the MysteriousHang website. (I modified it to keep sending the change notification in a loop ).
How should I be handling creating and running the new form? Does it matter that the form is created on the background thread even if its handle isn't created yet?
I'm also confused about the terminology "UI thread".
A UI thread is a thread that pumps a message loop. And operates in a mode that's compatible with user interface objects, it needs to be an STA, a Single Threaded Apartment. That's a COM implementation detail that matters a great deal to common UI operations that are not thread-safe and require an STA, like Drag+Drop, the Clipboard, shell dialogs like OpenFileDialog and ActiveX components.
It is the CLR's job to call CoInitializeEx() and select the apartment type. It does so guided by the [STAThread] attribute on the Main() entrypoint in your program. Present in projects that create UI objects like a Winforms or WPF app. But not a console mode app or service. For a worker thread, in other words a thread that was created by your code instead of Windows, the apartment type is selected by what you passed to Thread.SetApartmentState() method. The default is MTA, the wrong flavor. A threadpool thread is always MTA, that cannot be changed.
The SystemEvents class has the unenviable task of figuring out which thread is the UI thread in your program. Important so it can raise events on the correct thread. It does so by using a heuristic, the first thread that subscribes an event and is an STA thread is considered suitable.
Things go wrong when that guess wasn't accurate. Or certainly in your case where you try to create multiple threads that create UI objects, the guess can only ever be correct for one of them. You probably also forgot to call Thread.SetApartmentState() so it won't be correct for any of them. WPF more strongly asserts this and will generate an exception when the thread isn't STA.
The UserPreferenceChanged event is a trouble-maker, it is subscribed by some of the controls you find on the toolbox. They use it to know that the active visual style theme was changed so they'll repaint themselves, using the new theme colors. A significant flaw in the event handlers in some of these controls is that they assume that the event is raised on the correct thread, the same thread that created the control object.
This will not be the case in your program. The outcome tends to be unpleasant, subtle painting problems are a minor flaw, deadlock is certainly possible. For some reason, locking the work station with Windows+L and unlocking it is particularly prone to causing deadlock. The UserPreferenceChanged event is raised in that case because of the desktop switch from the secure desktop the user's desktop.
The controls that listen to the UserPreferenceChanged event and do not use safe threading practices (using Control.BeginInvoke) are DataGridView, NumericUpDown, DomainUpDown, ToolStrip+MenuStrip and the ToolStripItem derived classes, possibly RichTextBox and ProgressBar (unclear).
The message ought to be clear, you are using unsafe threading practices and they can byte. There in general is never any point to creating UI on a worker thread, the main thread of a Winforms or WPF program is already quite capable of supporting multiple windows. Short from avoiding the dangerous controls, this is what you should strive for to get rid of the problem.
I have a large project that I'm working on in C#, a language I'm fairly new to. The project heavily relies on a GUI and there is a lot of data that is displayed. Recently, we've been getting cross-threading errors in places that they never were before. These errors where they occurred were easily solved:
if (logListView.InvokeRequired)
{
logListView.BeginInvoke(new MethodInvoker(
() => logListView.Items[logListView.Items.Count - 1].EnsureVisible()));
}
else
{
logListView.Items[logListView.Items.Count - 1].EnsureVisible();
}
My question however, is this: Does that method need to be applied EVERY TIME I access a Windows Form object? Are there special cases? I'm not using multi-threading, so to the best of my knowledge where these errors occur are out of my control. E.g. I can't control which piece of code is executed by which thread: C# is doing all of that on it's own (something I don't really understand about the language). Implementing an if statement for each line that modifies the GUI seems exceptionally obnoxious.
You only need that code if you access winform components from outside the UI thread (ie. from any thread you have spawned). There are some components in the core library that spawn threads, for example the FileSystemWatcher. Winforms doesn't just spawn threads on its own, it only has the UI thread. Any cross-thread issues occur because of code you wrote or libraries you use.
You only need to invoke the code when the code is not running in the GUI thread.
I can't control which piece of code is executed by which thread
Yes, you can. There is nothing unpredictable about which code runs in the GUI thread, you just have to find out what the rules are.
The only code to run out of the GUI thread in your code would be methods that runs as an asynchronous callback, for example a timer or an asynchronous web request. (The System.Windows.Forms.Timer runs the Tick event in the GUI thread though.)
(There are other ways of running code in another thread, but then you would be aware of using multi-threading.)
Environment: .net 3.5 WinForms application
I am looking for some ideas how to stop / interrupting a Windows Form application, e.g. when “something” takes too long.
A typical scenario is reading large amount of data from a backend system and the user shall be able to press some key immediately stopping the loading.
Normal events are not responsive enough, since the backend call somehow consumes so much time, they are not reacting in promptly fashion.
In my read methods I have added explicit checks – but I cannot add such checks in 3rd party frameworks. Also it is somehow not a very nice approach.
Maybe someone has an idea how to reliable and promptly stop some running methods. Is there an interrupt I can use?
Regards HW
Normal events are not responsive enough, since the backend call somehow consumes so much time
That's not how it works. Understand the "message loop" is pretty important, be sure to read up on it. In a nutshell, Windows can only tell your program that a button was clicked when the main thread of program is idle. Your main thread should always be idle, ready to jump into action when some bit of work needs to be done. Like painting your form or processing a keystroke. Or doing something when the user clicks the Cancel button.
Which means that something else needs to do the heavy lifting. A thread. By far the best way to get started in the troublesome world of threading is the BackgroundWorker class. It has a CancelAsync() method, explicitly designed to do what you want to do. Be sure to review the code sample provided in the MSDN Library article for this method.
Execute the long running code in a separate Thread.
Thread thread;
void StartLong()
{
thread = new Thread(SomeMethod);
thread.Start();
}
void SomeMethod()
{
//Long running code here.
}
void CancelButton_Click(object sender, EventArgs e)
{
//...
thread.Abort();
}
If you don't have control over the code that takes long to execute. All you can do do cancel it is to abort the thread. thread.Abort();
You should do "long" =eveything longer than 1/5sec operations in seperate threads.
The best way of topping an operation is giving it some kind of "context" with a variable wich tells the workerthread wether the user wants to abbord the operation or not.
If you have no control over the code doing the operation and the code is .net you may call Thread.Abort() but if the code is not .net the only thing you can do is callinfg the windows api function "terminatethread" but you may get some resource leaks and files not beeing closed so you should think of using a childprocess.
You may consider using the BackgroundWorker class, it abstracts out working directly with threads, so is a little easier to implement. You just create an instance of BackgroundWorker and attach some event handlers to it. Here is an example.
I'm writing a J2ME application. One of the pieces is something that polls the contents of a directory periodically, and, if there are any new things, paints them on the screen. I've done this by having the UI form launch a polling thread with a pointer back to itself, and when the polling thread finds something it calls back to the form and calls a syncrhonized method to update it's display. This seems to work fine.
The question I have is this. In C#/.NET I know it is not nice to have non-UI threads updating the UI, and the correct way to handle this is to delegate it up to the UI thread.
E.g. the following:
public void DoSomeUIThing()
{
if (this.uiComponent.InvokeRequired)
{
this.uiComponent.Invoke(someDelegateThatCallsBackToThis);
}
else
{
this.uiComponent.Text = "This is the update I want to happen";
}
}
Is there a J2ME equivalent for how to manage this process? How about Java? Or does Java/J2ME just play nicer in regard to this? If not, how is this done?
[EDIT] It appears that Swing supports what I'm asking about via the SwingUtilities.invokeLater() and invokeAndWait() methods. Is there an equivalent framework for J2ME?
Regarding Java, what you are describing looks like a SwingWorker (worker thread).
When a Swing program needs to execute a long-running task, it usually uses one of the worker threads, also known as the background threads.
A Swing program includes the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
Single-thread rule:
Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.
When used in a J2EE context, you need to be careful when you are referencing a SwingWorker from an EJB.
Regarding J2ME, it depends if you are developing your application as a standard MIDlet that will run on any MIDP-enabled device, or for instance as a RIMlet, a CLDC-based application that uses BlackBerry-specific APIs and therefore will run only on BlackBerry devices.
Because unlike MIDP's UI classes, RIM's are similar to Swing in the sense that UI operations occur on the event thread, which is not thread-safe as in MIDP. To run code on the event thread, an application must obtain a lock on the event object, or use invokeLater() or invokeAndWait() – extra work for the developer, but sophistication comes with a price tag.
But for LCDUI, you can access a form from multiple threads.
There are many profiles of Java ME. If you mean MIDP then Display.runSerially is what you want.
For AWT (Swing) you would use EventQueue.invokeLater (SwingUtilities.invokeLater is only necessary due to Java 1.1 not having the EventQueue method - 1.2 is about to celebrate its tenth birthday). For the Common DOM API, use DOMService.invokeLater.
No matter what claims a GUI API may make about thread-safety they are probably wrong (some of the claims of Swing are removed in JDK7 because they are not implementable). In any case, application code unlikely to be thread-safe.
For j2me apps you probably want to keep it simple. The main thing is to touch UI components only in the event thread. The direct way of doing this is to use invokeLater or invokeAndWait. Depending on your libraries you won't have access to anything more than that. In general if these aren't provided in your platform it probably equates to there being no thread support and not being an issue. For example the blackberry does support it.
If you develop under SWT this is accomplished by means of asyncExec() method of Display object. You pass an object implementing Runnable so the UI thread executes the changes done in other thread.
This is an example borrowed from here
public void itemRemoved(final ModelEvent me)
{
final TableViewer tableViewer = this.viewer;
if (tableViewer != null)
{
display.asyncExec(new Runnable()
{
public void run()
{
tableViewer.remove(me.getItem());
}
}
}
}
I can attest that the MIDP UI toolkit is indeed thread-safe, as I have large MIDlets with complex GUI running on millions of phones made by almost every manufacturer, and I have never seen a problem in that regard.