I need to write an application in c# that keeps track of multiple tasks, each being implemented as a class instance running on its own thread. A user interface will be used to display the status of each task instance depending on which task I select from tree view which will display the list of tasks.
An idea I have is to create some other class, called PropertyClass which will have an instance of the TaskClass and some properties relating to this TaskClass instance. Then whenever the TaskClass instance changes its state the related property in the PropertyClass instance will get updated and then the UI will be updated with these property values from the PropertyClass when the task is selected from the Tree View list.
There will probably be hundreds of these tasks running which will be communicating with a service on a remote machine.
How else can I go about coding this solution in an efficient way?
Read this document from the MSDN on the Task Parallel Library first.
I have a few suggestions.
First, you need a way to make sure you don't end up with threads blocking your app from closing. One sure fire way to do this is to make sure all your threads are background threads. That can be a little problematic if you have to make sure a thread's work is done before it is joined or aborted.
Second, you could look at using the ThreadPool class which should make creating and using threads more efficient. The thread pool is there to help you manage your threads.
Third, you will need a method of synchronizing your data access from the GUI to data in the other threads. In WPF you use the Dispatcher and in WinForms you'll use Invoke.
Forth, the BackgroundWorker class can help with all of these if it'll fit in the model of your application.
Fifth, events and delegates can be BeginInvoked which essentially puts them on another thread. It's kind of implicit multi-threading and can be useful.
Sixth, and I've not yet had the chance to use this, .Net 4 has the Parallel Task Library that may be of use to you.
Seventh, safe shared data access and synchronization can be accomplished using lock and/or Monitor.
Hope this helps.
-Nate
If each TaskClass instance corresponds to a node on the tree view, you can store the TaskClass instance in the tree view item's Tag property. Or you could create a dictionary of TaskClasses, keyed by a unique identifier such as a GUID, and store the identifier in the Tag property.
In either case, use a callback method to signal that a TaskClass instance has an update.
Related
I am developing a C# desktop application (Windows Forms) with MVC and I want to use threads because I think it will provide me a more fluid interaction with the view to the final user, I will try to explain my best what I want.
I implemented MVC like this:
View -> has several controls that trigger events, these events are
subscribed by the controller
Controller -> receives some information from these events and passes
it to model by calling the adequate method, like this
Program.model.methodX(data)
Model -> processes the information and sends the data to the view by
triggering events that are subscribed by the view so it can update
itself
What the model actually does is communicate with a PLC to get some data from certain registers, while its doing this the view is freezed waiting for the reply.. I tried to implement threads in the model, because I think its the appropriate place for this, the problem is that I need to pass some information for the thread (number of registers etc) which is a problem because the thread wants a method that returns void and has no parameters (ThreadStart), and in the end send the data to the view by triggering an event which is a problem because it wants an object reference if it's a non-static method, field or property etc.. Is there any way I can achieve this or am I thinking all wrong?
Thank you all in advance.
I feel like you have a couple of questions in there, but I will try to address them:
You can pass parameters to a thread but you need to use ParameterizedThreadStart which allows the passing of an object.
In regards to passing data in and getting data back, you should probably look into using the TaskFactory and specifically the StartNew methods which will create a new Task. You can pass lambdas, methods that take parameters, and functions which will return a result and then you can use the task object to wait for and retrieve the result. For more info on threading including some insight into using the TaskFactory check out this link from Joseph Albahari on threading. It is an excellent resource.
In the general sense there are numerous techniques for getting data in and out of a thread. You can pass the this parameter in and then have access to all of its members, just remember that you are dealing with multiple threads and so need to be careful with reading/writing data. If there is shared data you will need to protect it with some form of locking. If you don't have to share the data while the thread is running, I would probably make a class to hold the data I need to pass that to the thread and do the same for the result. Then you can just use the TaskFactory.StartNew to launch the task and pass the data in and use the result of the task to get the data back out.
I have the following situation.
Multiple forms that display information stored in a shared object. A background worker thread that is constantly updating the shared object.
I thought about having the shared object be something like a singleton but I am worried about the multi threading concerns.
What is the best way to solve this kind of problem?
I was asked what is the problem but I thought I covered that but I will try to add more detail.
Ok I have one lets say an object like this
public class Connections
{
public List<User> Users {get;set;}
public List<Computer> Computers {get;set;}
}
Then I have 2 different forms that are open at the same time. One form is for displaying the Users, the other is for displaying the Computers.
Next I have a background thread that is populating the Users and Computers.
How can I share the data that the background thread is building with multiple forms?
Any data shared between the background thread and the UI thread needs to be protected by locks. That is, you need to pick an object to synchronize on (possibly the "main object" that's being shared, if there is one), and anytime you modify or read a member variable from that object, you need to first lock on it.
Alternatively, you could use Control.Invoke() from the background thread anytime you need to update data so that only the UI thread will actually modify the shared object, making it effectively no longer shared between threads.
A simple and clean way to solve this problem is by using Tasks (System.Threading.Tasks) instead of a BackgroundWorker. Pass in a SyncronizationContext created on a UI thread and the framework does all the locking work for you.
From my reading:
WPF objects use an executing thread to store state (known as thread affinity). This means they have to communicate on the same thread they were created on. The DispatcherObject allows these WPF objects to communicate on the same thread.
Is the above correct? The stuff about storing state came from the msdn link below.
What are the WPF objects communicating to each other? I read something about a message pump. Does that mean they are passing events to each other and by being on a single thread, it ensures that they are passed in order?
What specific state are they storing?
Some details: http://msdn.microsoft.com/en-us/library/ms750441.aspx#System_Threading_DispatcherObject
The section you linked to actually explain this: Theoretically, WPF might not need thread affinity. But many old objects do, and WPF needs to work nicely with them.
I am creating a custom video player in a C# form. At present the player has a initialising and shutdown routines and a thread running in the background reading video frames and displaying them. I am fairly new to C# so I am trying to establish how best to send the start\stop\pause commands from the GUI thread to the video thread. Should I just use a state variable protected with a lock and poll this every time round my video thread; are there
any other recommendations?
Thanks.
A polled state variable would seem the easiest solution providing your video thread loops regularly enough.
You may not even need a lock, making the state variable volatile should be sufficient in C# providing only one thread updates it. (volatile in C# has slightly different semantics than C, and should guarantee that the other thread picks up the new value)
Several ways are possible. As you are new to C# and probably tightly coupled to UI, I suggest you to use BackgroundWorker class.
http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
You can pass your arguments using DoWorkEventArgs of DoWork event.
Also with such approach and without shared objects (through threads) you can avoid using lock or synchronization
I think it could be best solution for you, but there are alternatives. You can use Asynchronouse Programming Model (APM), or even Thread/ThreadPool, or Task Parallel Library.
Should I just use a state variable protected with a lock and poll this every time round my >>video thread; are there any other recommendations?
If you have shared state like a video thread, than you should use thread synchronization. So, answer will be yes, you should use some protected variable, you can avoid locking by using just volatile, but consider to use other sync primitives. Because using volatile just ensures that you are reading/writing most actual value, but it doesn't prevents other thread from reading/writing.
Some links to choose whether to use lock(other primitives) or just a volatile:
Do I need to lock or mark as volatile when accessing a simple boolean flag in C#?
Volatile vs. Interlocked vs. lock
You should be able to call start/stop/pause the DirectShow filter graph without limitations. This would cause respective method calls on your source filter (for more information, see Filter States). The source filter does need to notify the background thread about the state change, if this has not been done already.
The synchronization can be implemented in the same way as in DirectShow classes, where two AutoResetEvent instances are used in the filter, one to notify background thread about new request, and one to notify calling thread about the request processing being completed.
Being new to using threads etc in UI's, can I ask is the following simple design seem OK. Refer to diagram image at link here
In particular:
a) use of backgroundworker & backgroundworker ProgressChanged to have the aggregator work on a separate thread. So I would need a custom class/type that had all the data I'd need to pass back from the aggregator thread to the UI thread I assume.
b) create a separate thread within the aggregator to ensure that the SharpPCap/WinPCap callback method is in a different thread. So this Capture Manager thread writes packet results to a shared Buffer. I'm assuming here that if the code can see the buffer variable that they can both access it, irrespective of which thread they're running in?
thanks
I have a couple suggestions:
I wouldn't recommend using a BackgroundWorker and ProgressChanged for this. Given that you want to "poll and aggregate" every 1 second, I'd recommend just using a Timer (probably a DispatcherTimer). You can use Dispatcher.BeginInvoke to marshal the calls back onto the UI thread, if you have this run in a separate thread (you can also use a UI-thread based timer, if you want).
I'd recommend using a ConcurrentQueue<T> to hold your packet data, instead of a list. This will prevent you from needing locking around your list. If you must stick to versions of .NET <4, you can use a List<T>, but you'll need to synchronize access to it (lock on some object to protect read/write operations in the list). Both threads will be able to use the same collection, provided it's thread safe or synchronized correctly.