I'm working on integrating a single-threaded API that does not have any multi-threaded support into a multi-threaded program. I would like to keep all APIinteraction on the main thread and do other stuff on other threads. However the program I am working with has a Producer-Consumer oriented threading design(which I can't modify).
Is there a way I can make threads switch to main thread when I want? Or some other way to get it working?
I apologize for not being able to express the problem clearer
You can use Control.Invoke on a worker thread to have it run some code on the main user interface thread.
Or maybe you could just synchronize all access to the single-threaded API using lock?
More details would be great, but those are some ideas to get you started.
EDIT: After reading your comment, the easiest & most light-weight way to do it would be to synchronize using lock, as previously mentioned. That way, only one thread calls the 3rd-party API at a time. Example:
static object APILock = new object(); // global variable
// Do this anytime you need to make calls on this non-thread-safe API:
lock (APILock) {
// call the API; only one thread will run code inside the lock at a time
}
This is generally the accepted way of calling non-thread-safe code.
You can try to use window messages that are (usually) handled by one "main" thread. Create a window, expose wrappers that mimic your API methods to clients, and send window messages internally. When you handle window messages, call your actual implementation.
That is how COM single-thread apartment model works, and it solves exactly the same problem. However, that is quite advanced solution.
Can't your code be refactored in order to make it thread-safe? That would be simpler, I think.
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 am trying to leverage .NET 4.5 new threading capabilities to engineer a system to update a list of objects in memory.
I worked with multithreading years ago in Java and I fear that my skills have become stagnant, especially in the .NET region.
Basically, I have written a Feed abstract class and I inherit from that for each of my threads. The thread classes themselves are simple and run fine.
Each of these classes run endlessly, they block until an event occurs and it updates the List.
So the first question is, how might I keep the parent thread alive while these threads run? I've prevented this race condition by writing this currently in a dev console app with a Console.read().
Second, I would like to set up a repository of List objects that I can access from the parent thread. How would I update those Lists from the child thread and expose them to another system? Trying to avoid SQL. Shared memory?
I hope I've made this clear. I was hoping for something like this: Writing multithreaded methods using async/await in .Net 4.5
except, we need the adaptability of external classes and of course, we need to somehow expose those Lists.
You can run the "parent" thread in a while with some flag to stop it:
while(flag){
//run the thread
}
You can expose a public List as a property of some class to hold your data. Remember to lock access in multithreading code.
If the 'parent' thread is supposed to wait during the processing it could simply await the call(s) to the async method(s).
If it has to wait for specific events you could use a signaling object such as a Barrier.
If the thread has to 'do' things while waiting you could check the availability of the result or the progress: How to do progress reporting using Async/Await
If you're using tasks, you can use Tasks.WaitAll to wait for the tasks to complete. The default is that Tasks and async/await use your system's ThreadPool, so I'd avoid placing anything but relatively short running tasks here.
If you're using System.Threading.Thread (I prefer using these for long running threads), check out the accepted answer here: C# Waiting for multiple threads to finish
If you can fetch batches of data, you can expose services allowing access to the shared objects using self hosted Web API or something like NancyFX. WCF and remoting are also options if you prefer binary communication.
Shared memory, keep-alive TCP connections or UDP are options if you have many small transactions. Perhaps you could use ZeroMQ (it's not a traditional queue) with the C# binding they provide?
For concurrent access to the lists take a look at the classes in System.Collections.Concurrent before implementing your own locking.
I am using the class HttpListener as a web server. This server runs on a different thread.
At some point this server needs to run some code but it needs to be executed on the main thread. Is there an easy way of doing that?
Thanks!
The bigger question is:
Why do you need to run it on the parent thread? Is it UI Code modifying the UI? Do you need to be within that thread's context to gaurantee thread saftey?
It might be worth stepping back and re-evaluating your threading model, you may be trying to do things in the wrong place.
I Suggest you read This Excelent Free E-Book on C# Threading and learn about the alternate ways of inter-thread communication and look into the Dispatcher if you're using WPF, as it will help delegate events back to the UI Thread if that's what your intent is.
Quick & Dirty Solution Not really the best way
There's any number of ways to approach this, the simplest would probably to have a list of delegates to execute on the main thread. Each time your main thread spins, you lock the collection (unless you're using the multi-threaded collections) and copy out the delegates & clear the collection and release the lock.
Then you simply run them on the main thread.
The problem you'll run into is if you're using blocking on the main thread, your spin cycle will not pass across your delegates till your blocking stops. So if you're say, blocking while you wait for connections, your code will not run till a new person connects.
You could put the server's listen port on it's own thread to solve this.
To do something on the main thread, you will possibly want to inject it via Invoke(), or in the main loop will have some queue of things to do that will be injected from the 'other' threads, in this case HttpListener.
Your example seems similar to mine, where I have 300 threads handling stream ripping, and they are all 'calling' main thread by putting the string messages into the queue for it. It works like a charm. However, when I did try (I dared, just to see what will happen) to Invoke() from at least 30-ish threads to the main message loop, it was weird, to say the least.
Best: use simple Queue< something >, and enqueue it from the other thread, then dequeue it from the UI thread.
I know the BackgroundWorker should not be used in Windows Services but would anyone have a good online reference explaining why?
BackgroundWorker relies on a current SynchronizationContext being set in order to function. It's really intended and designed specifically for working with UI code.
It's typically better in a service to self-manage your threads, since there are no UI synchronization issues. Using the threading API (or .NET 4 Task API) is a much better option here.
Well, it's okayish to use a BGW in a service, it just doesn't do anything especially useful. Its reason for being is its ability to raise the ProgressChanged and RunWorkerCompleted events on a specific thread. Getting code to run on a specific thread is a very non-trivial thing to do. You cannot simply inject a call into the thread while it is executing code. That causes horrible re-entrancy problems. The thread has to be 'idle', in a state where inject code doesn't cause trouble.
Having a thread in an idle state is a fairly unnatural condition. You use threads to run code, not for them to be idly spinning its heels. This is however the way a UI thread works. It spends 99% of its time in the message loop, waiting for Windows to tell it to do something. A button click, a paint request, a keyboard press, that sort of thing. While it is inside the message loop, it is in fact idle. A very good time to execute injected code.
Which is what Winforms' Control.Begin/Invoke and WPF's Dispatcher.Begin/Invoke do. They put a delegate in a queue, the queue is emptied and the delegate targets executed by the message loop. The WindowsFormsSynchronizationContext and DispatcherSynchronizationContext classes are the synchronization providers that uses them. Winforms and WPF replace SynchronizationContext.Current with an instance of them. Which in turn gets used by BGW to raise the events. Which makes them run on the UI thread. Which allows you to update the non thread-safe user interface components from a worker thread.
You can probably see where this is heading, a service uses neither. The default synchronization provider doesn't synchronize anything. It simply uses a threadpool thread to call the Send or Post callback. Which is what will happen when you use BGW in a service. Now there is actually no point at all in having these events. You might as well let the DoWork handler call the event handling methods directly. After all, the thread on which DoWork runs is just another threadpool thread as well.
Well, no real harm done, other than making it quite a bit slower.
I've used BackgroundWorker in windows services many times without any ill effect. While its use of SynchronizationContext may be unnecessary, I haven't observed it causing problems or poor performance.
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.