I have a static class called Monitor that includes a method LogToMonitor.
public static void LogToMonitor(MonitorDevice device, MonitorCategory category, MonitorType type, string msg)
It creates a MonitorEntry type and updates a property which does a property change to the UI and adds to an ObservableCollection.
public ObservableCollection<MonitorEntry> MonitorEntries { get; }
I now have another thread that needs to LogToMonitor. This is going to cause issues having multiple calling threads. I'm thinking I should have a Producer Consumer approach.
What type of collection should I use?
Should the Queue be a separate class which processes the calls and updates the UI?
Can I have multiple threads still call LogToMonitor method which puts them in the Queue?
BlockingCollection<T> is what you are looking for probably. It's an implementation of the Producer-Consumer pattern. https://learn.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview
ObservableCollection is not thread-safe so you can run into exceptions. Check the post of Robert Fraser, he has posted the code for a thread safe ObservableCollection. Use this instead of the standard implementation and should not have problems with multiple threads. How to make ObservableCollection thread-safe?
Related
I'm wondering what I need to do to make models thread safe in MVVM. Say I had the following class, which is instantiated as a singleton:
public class RunningTotal: INotifyPropertyChange
{
private int _total;
public int Total
{
get { return _total; }
set
{
_total = value;
PropertyChanged("Total");
}
}
...etc...
}
My view model exposes it via a property:
public RunningTotal RunningTotal { get; }
And my view has a textblock bound to it, i.e. {Binding Path=RunningTotal.Total}.
My app has a background thread that periodically updates the value of Total. Assuming nothing else updates Total, what (if anything) should I do to make all this thread-safe?
Now, what if I wanted to do something similar but using a property of type Dictionary<>, or ObservableCollection<>? Which members (add, remove, clear, indexer) are thread-safe? Should I use a ConcurrentDictionary instead?
My app has a background thread that periodically updates the value of Total. Assuming nothing else updates Total, what (if anything) should I do to make all this thread-safe?
For scalar properties, you don't need to do anything special; the PropertyChanged event is automatically marshaled to the UI thread.
Now, what if I wanted to do something similar but using a property of type Dictionary<>, or ObservableCollection<>? Which members (add, remove, clear, indexer) are thread-safe? Should I use a ConcurrentDictionary instead?
No, this is not thread-safe. If you change the content of an ObservableCollection<T> from a background thread, it will break. You need to do it on the UI thread. An easy way to do it is to use a collection that raises its events on the UI thread, like the one described here.
As for Dictionary<TKey, TValue>, it doesn't raise a notification when its content changes, so the UI is not notified anyway.
Say that there are two threads updating Total, and you want to log all changes to _total in the PropertyChanged method. Now there is a race condition in which PropertyChanged can miss a value. This happens when a thread blocks in the middle of calling set_Total. It updates _total but does yet call PropertyChanged. In the meantime, another thread updates _total to another value:
thread1: _total = 4;
thread2: _total = 5;
thread2: PropertyChanged("Total");
thread1: PropertyChanged("Total");
Now, PropertyChanged is never called with the value of 4.
You can solve this by passing the value to the PropertyChanged method, or by using a lock in the setter.
Since you say that you have one thread which updates this property, there is no possibility for a race condition. This is only the case when multiple threads (or processes) update the same thing at the same time.
The model should be written in a thread-safe way just like any code must be; it's up to you to determine whether you are using locks, concurrent containers or anything other to do it. The models are just library code, which (almost) shouldn't know that its functionality is going to be consumed by a MVVM application.
The VMs, however, have to work in the UI thread. This means that typically they cannot rely that the events from model are coming in the UI thread, so they have to marshal the calls or store them in a task queue if the subscribed events are coming not at the UI thread.
So, the VM is the place which should care about thread safety in a specific way, more than the model needs to.
The View code, in turn, can usually live in happy ignorance about all the threading issues: it gets all the messages/calls/events/whatever in the dedicated UI thread, and makes it own calls in the UI thread as well.
Specifically for your case, your code is not the model but VM, right? In this case you have to fire your events in the UI thread, otherwise the View will be unhappy.
This question provides a thread-marshalled version of the ObservableCollection
How do you correctly update a databound datagridview from a background thread
However, you still need to worry about contention between threads, which would require you to lock resources when they are updated, or use something like Interlocked.Increment.
If one thread is updating, and another is reading, there exists the possiblity that a read is done half way through an update (For example, an Int64 is being modified. The first half (32 bits) has been updated in one thread, and before the second half has been updated, the value is read from a second thread. A completely wrong value is read)
This may or may not be a problem depending on what your application is going to do as a result. If the wrong value will be flashed on the GUI for 1 second, then its probably not a big deal, and the performance penalty of the lock can be ignored. If your program is going to take action based on that value, then you probably need to lock it down.
A simple answer is that you need to schedule the property updates in UI Thread through UI Thread's Dispatcher. This will put updates operation in a queue which will not crash the application.
private void handler(object sender, EventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { updates(); });
}
private void updates() { /* real updates go here */ }
Some thing more elaborate that it is actually so simple... When instantiating your viewmodel in your view just pass the dispatcher down in the ctor.
ServerOperationViewmodel ViewModel;
public pgeServerOperations()
{
InitializeComponent();
ViewModel = new ServerOperationViewmodel(Dispatcher);
}
Then in your View model:
Dispatcher UIDispatcher;
public ServerOperationViewmodel(Dispatcher uiDisp)
{
UIDispatcher = uiDisp;
}
And use it like a normal UI dispatcher.
UIDispatcher.Invoke(() =>
{
.......
});
I will admit that I am still fairly new to MVVM, but I don not think this breaks the MVVM motto.
I'm jusing Jurassic javascript compiler to run javascript in my C# application. Now, jurassic isn't thread-safe, and I call functions (in javascript) from threads all over the place, which I figured wasn't that smart. What I could do was ofcause just to create a simple lock on the javscript-engine, however, what I want is a programming model similar to the one you have when working with a GUI thread in WPF or WinForms. So, I spawned a thread, and created my javascript-engine inside that thread, and what I would like is that no other threads are allowed to edit the objects created in that thread (which will just be the javascript-engine and all the js-objectes). And then, to call js-code from other thread I'd like to use a dispatcher, or something similar, to make the js-thread run the code.
Is this possible in C#?
It doesn't quite answer your question but you may want to take a look at this MSDN article. It talks about the approach that WPF took with their objects and the Dispatcher model, as well as the Dispatcher, DispatcherObject and DispatcherSynchronizationContext classes.
What they recommend for individual objects is to inherit from DispatcherObject (which may not be feasible for your situation) and call the inherited VerifyAccess() method on public access.
public class ThreadOwnedObject : DispatcherObject
{
private string field;
public string ExposedProperty
{
get { return field; }
set
{
VerifyAccess();
field = value;
}
}
}
And the invocation would use the inbuilt Dispatcher.
ThreadOwnedObject ownedInstance = new ThreadOwnedObject();
ownedInstance.Dispatcher.Invoke(new Action(() => ownedInstance.ExposedProperty = "foo"));
Alternately, if that or the DispatcherSynchronizationContext in the article doesn't fit your needs, I imagine that you could probably create a mechanism that mimics the DispatcherObject by holding onto the Thread.CurrentThread.ManagedThreadId when an object is created and perform checks against that value for every exposed access. Beyond that or an equivalent, I don't think that there's a built-in mechanism that will associate a random object with a given thread.
I'm not quite sure what you are asking, but I'll try to help anyway.
Can you use a semaphore to lock the thread running the javascript engine? Even if you don't use the Semaphore class, you could use a boolean or "lock" keyword to protect the code block with the executing engine. The objects produced by that thread could be hidden by the class with the engine until you are ready. You could also expose a method in that class that would allow code injection or object fetching from behind the protected code.
I have a main thread which should process data coming from several worker threads.
But this data is not a specific class.
There are around 6-7 classes, and I need to pass one of this class to the main thread from worker threads.
Previously I had only one class which was passed across threads. I was using;
BlockingCollection<MyClass> mainQueu = new BlockingCollection<MyClass>(new ConcurrentQueue<MyClass>());
So I was pushing MyClass instances from several threads to mainQueu and main thread was trying to take from the mainQueu.
But what if I have more than one classes. Which way is better?
Having a queue for each type of class:
Of course there should be another queue of type maybe enum, specifying which class is pushed to the queue. And main thread always tries to take from this queue. As soon as any item comes, it will takes from related queue.
Casting:
Having only one main queue, and in mainQueue class, I can have object member.
And enum which specifies type of object member.
And I can convert class to object when pushing to queue, and than in main thread I can cast it back to original class.
Hope it is clear.
Many thanks,regards
A useful trick here is to just have the worker as a queue of delegates; for example, Action. Then the caller can enqueue the appropriate method and (via captured varialbes) any necessary state.
Say, for example, you have a void Enqueue(Action) method; the caller could do:
queue.Enqueue(targetObject.Method);
(where targetObject.Method is a void Method() {...}), or can do something like:
queue.Enqueue(() => SomeMethod(foo, bar, 123));
(where foo and bar are local to the code that wants the work done)
so we've passed lots of state at once, and not once had to think about types - just operations.
In my WPF try to separate my classes logic from any interface related data and only supply ObservableCollection properties for binding.
Problem is, when I access those binded OCs from other threads, I am required to do so through the dispatcher. The result is that I am required to add many Dispatcher.Invoke() calls, hidden inside my classes, whenever one of the methods attempts to update the OCs.
How can I do that in a more clean and separated way, so the dispatcher calls be abstracted away from my methods?
I don't have a silver bullet. But if you are certain and ready to take the responsibility of implicit UI delegation, you can always inherit from ObservableCollection, override methods and dispatch all requests to UI.
But the following code makes me scary:
// somewhere in thread pool:
for(int i = 0; i < 1000; i++)
{
_dispatcherAwareCollection.Add(i);
}
It seems innocent, but under the hood it blocks calling thread 1000 times. Alternatives might be your specific BulkXXX() methods, that will delay notification until all elements are processed. This solution is not perfect either, since you wanted an abstraction that could let you seamlessly swap collections, but BulkXXX() methods are very specific to new collection.
Option 1
I think you should look into a better separation of your code using the MVVM pattern, if you aren't familiar with it, I highly suggest to see the following video as it explains exactly what you're looking for.
Specifically, however, in your case you should have the model class with regular collection (e.g List) on which you do all the work in the threads. Your ViewModel should contain the ObservableCollections and connect loosely with the collections that exist in the model, e.g, you can choose to subscribe via an event from your ViewModel to a certain update logic in your model. You will STILL need to use Dispatcher to update the OC, but you will only need to do it once.
Option 2
You can instead just use the solution described here. Basically, he created a new derived class from OC that allows you to dispatch changes from the code automatically without you ever needing to update the dispatcher yourself.
The common approach is to have a Dispatcher property on your view model (probably in a base class for all view models) that can be injected outside. It is OK to have it in a view model because view model SHOULD be aware of UI concepts, but it should not be aware of particular view (layout, controls, etc.) and certainly it should not have a reference to the view.
What you can do is you can make it easier to dispatch your code to the Dispatcher thread by creating a helper or a service that will abstract the dispatcher away. For example, you can create a helper like this:
public class AsyncHelper
{
public static void EnsureUIThread(Action action)
{
if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(action, DispatcherPriority.Background);
}
else
{
action();
}
}
}
And whenever you need to update you observable collection, you wrap you code in that helper method:
AsyncHelper.EnsureUIThread(() =>
{
// Update you observable collections here
});
OR, you can go further and use AOP (e.g. PostSharp) to specify declaratively (using attributes) that a method should be executed in the UI thread.
And finally, please note that you have to dispatch only collection updates to the UI thread. Usual properties can be safely updated from a background thread. The updates will be dispatched to the UI thread automatically by the binding mechanism. Probably in future versions of WPF updates to a collection from a background thread also will be supported.
Well you could write yourself an AsyncObservableCollection, if you know how to write it threadsafe. Then you can encapsulate the Dispatcher calls in it.
The problem is you would not use the standard ObservableCollection delivered within the .Net - Framework. It would increase the risk of errors in your application.
Another option would be to implement a WrapperClass, which contains and exposes an ObservableCollection for binding and has methods to modify the collection.
public class WrapperClass<T>
{
public ObservableCollection<T> Collection {get; set;}
public void Add(T item)
{
//do your dispatcher magic here
}
...
}
To modify the collection you implement the methods in it. The problem here is, that there is no guarantee, that others will use these methods, too.
I am afraid that you will have to wait for the next version of wpf
From this post:
A few nuggets we can expect to see in the next version of WPF include:
Hosting of Silverlight content with the new SilverlightHost element, without airspace issues (the inability to overlap WPF content over native Windows hWnd content)
Overall better management of airspace with hosted native hWnd-based content like the WebBrowser, HwndHost and WindowsFormsHost
Enabling binding and change notification for collections that are created on a background thread
Better integration with UI virtualization
Integration of the Ribbon control
And more
Use SynchronizationContext instead of Dispatcher. SynchronizationContext is common feature for threads synchronization in .NET, meanwhile Dispatcher is intentionally developed for WPF.
You probably want to use something like MTObservableCollection. I've used this in a project and it worked fantastically. Basically, it does all the dispatching work for you when the collection changed event is raised, by analysing the thread that the handler was assigned from, and dispatching accordingly.
The article is well worth a read, even if you don't plan to take this option.
I have an extension for this:
public static class DispatcherInvoker
{
public static void AddOnUI<T>(this ICollection<T> collection, T item)
{
Action<T> addMethod = collection.Add;
Application.Current.Dispatcher.BeginInvoke(addMethod, item);
}
}
EDIT:
I stole it from an stackoverflow post but forgot from which one
I think you have to much coupling if you need to think about threading in your model layer.
What you should do is to not connect your model directly to the GUI. As others have said, use a layer in between (MVVM).
This means that you let your MVVM layer respond to the change notifications from your observable collection. It is the MVVM layer that decides if and how these notifications should be passed on to the GUI. Look here for a way to lower the update frequency of the GUI to keep it usable.
In short:
Keep using an ObeservableCollection in your model layer if you like but don't use it directly in the GUI binding. Let another layer receive the notifications and control the GUI update.
I have a class that handles events created by multiple member objects. Events from these objects spawn worker threads for the event, so that the various event handlers in my class are running on different threads (one is a serial handler, one is a timer event, etc.) I'm looking for a simple way to make my code thread-safe, preferably by forcing the event handlers to run on my object's thread.
If this were a Forms UI object, I could take advantage of its implementation of the ISynchronizeInvoke interface, and make calls to InvokeRequired, Invoke, etc. In WPF I could use a Dispatcher object. But my class needs to run *independently of any UI code.
Here's a simplified example of what I have:
public class MyClass
{
private SomeObject object1;
private AnotherObject object2;
public MyClass()
{
object1 = new SomeObject();
object2 = new AnotherObject();
object1.AThreadedEvent += ThreadedEventHandler1;
object2.AnotherThreadedEvent += ThreadedEventHandler2;
}
// This runs in its own thread!
private void ThreadedEventHandler1()
{
// DO STUFF HERE
}
// This runs in its own thread!
private void ThreadedEventHandler2()
{
// DO STUFF HERE
}
}
Because both event handlers access the same objects in the parent class (including each-other!), it would be awesome if there were a simple way to force the event handlers to run in the creating object's thread.
I've toyed with the idea of having my class implement the ISynchronizeInvoke interface, but it appears that doing so can get pretty complicated. Before I jump down that rabbit hole, I thought I'd ping the experts to see if there is a more simple solution.
Thoughts?
EDIT:
Part of the reason I want to run the event handlers in the parent object's thread is because the parent object has it's *own events that are triggered based on the events sent by its member objects. I'd like any threading functionality to be hidden by this class, so that code that uses the class doesn't have to worry about thread-related issues (ie. locks and so on). Simply locking shared data won't do the job, because I *still need to trigger events from within the threaded event handlers.
The ideea of invoking on another thread is hand to hand with having a while loop that from time to time it checks whether there is an "outside" message to be processed. For UI, there is the windows loop that does that. For an external thread, you must write manually a loop. Imagine a situation without a loop and that you have a relative long running thread right ? and sudently you want to interrupt this thread to invoke your message and resume what it was doing ON THE SAME shared stack memory. This interruption would destroy your stack. This is simply NOT possible. The other possibility is to use a synchronization mechanism such as ManualResetEvent and just wait for a signal (a signal that comes outside your thread). So, to resume, in order to process a message from another thread, you basically have only two options:
1) You have a while loop, eventually using a little sleep (to give some time / ticks to other threads to do their job)
while (true) {
Thread.Sleep (5);
if (someMessageArrived) { ... }
}
2) You just wait for a message implementing somehow the producer / consummer architecture:
On listening thread:
aManualResetEvent.WaitOne ();
On the "producer" thread:
aManualResetEvent.Set ();
There are advanced classes in .NET framework that might help such as BlockingCollection.
Hope this helps
Assumming, that your class runs in its own thread that the only logic is to execute the incomming calls from other threads, this would be the solution:
(comments inside)
public class MyClass
{
private SomeObject object1;
private AnotherObject object2;
public MyClass()
{
object1 = new SomeObject();
object2 = new AnotherObject();
object1.AThreadedEvent += ThreadedEventHandler1;
object2.AnotherThreadedEvent += ThreadedEventHandler2;
}
// This runs in its own thread!
// Only add the real function call to the queue
public void ThreadedEventHandler1()
{
tasks.Add(ThreadedEventHandler1_really);
}
private void ThreadedEventHandler1_really()
{
// DO STUFF HERE
}
// This runs in its own thread!
// Only add the real function call to the queue
public void ThreadedEventHandler2()
{
tasks.Add(ThreadedEventHandler2_really);
}
// here is the actual logic of your function
private void ThreadedEventHandler2_really()
{
// DO STUFF HERE
}
// the queue of the tasks
BlockingCollection<Action> tasks = new BlockingCollection<Action>();
// this method never returns, it is blocked forever
// and the only purpose of i is to do the functions calls when they added to the queue
// it is done in the thread of this instance
public void StartConsume()
{
foreach (Action action in tasks.GetConsumingEnumerable())
{
// add logic before call
action();
// add logic after call
}
}
}
The solution based on that the caller threads tat calls the functions: ThreadedEventHandler1 and ThreadedEventHandler2, actually add the real call to the queue and emediately continue with their run.
From the other hand, StartConsume function iterates the queue and makes the calls of the added method calls. If you want to add another logic before and after call, you can add it in this function.
Hope it helped to achieve your goal.
Without completely understanding the rational behind your design. I can say that the problem you are trying to solve was solved many times before.
I will assume your main object is like a service which expects calls (in this case events) from itself and other services (the sub objects). If you would think about it in terms of services (which you arguably should) WCF solves that problem for you doing all the heavy lifting #Rami suggested.
You define the main service with the following behavior:
Instance Context Mode - Single
Concurrency Mode - Single
More about these here.
And every event handler would call that main service notifying it about the event.
I am pretty sure you would not go that far and implement every class as a service, but thought it is worth offering anyway as an option.
OK, based on all of your feedback (thanks!) I have a solution to my problem. The short answer: what I wanted to do isn't possible.
Here are more details for those who asked. I'm writing a DLL that manages a device attached to a serial port. This includes basic serial port COM (packet TX and RX, including parsing), and higher-level protocol behavior (TX, Ack, retry on timeout, etc.) The serial port event handlers provided by .NET are obviously asynchronous, as are the System.Timers.Timer objects that I use to handle timeouts, etc.
I am building the code around an MVVM architecture, so that my UI doesn't have any logic in it whatsoever. Hence my need to avoid exploiting Dispatcher or Invoke functionality provided by the UI.
What I was looking for was a way to handle asynchronous events within my DLL in the same simple manner provided by WinForms and WPF. But as has been pointed out, and as I learned when digging deeper, what you are *really doing when you call BeginInvoke or a Dispatcher is pushing something onto a queue, to be consumed later by a different thread polling the queue. Outside the context of a UI, no such polling architecture exists.
SO. My options are to lock the shared objects in my class to make it thread safe, or to implement my own polling architecture within another thread (to avoid blocking the program that uses the DLL) that emulates what the UI code already does.
In either case, the UI code will still need to use its Invoke or equivalent tools when handling events from the DLL class. I suppose that's OK.