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.
Related
I'm writing an application for WPF in MVC pattern. The purpose of application is to display some data in the database and these data are being updated asynchronously.
I'm thinking about how to design the architecture, such that it will be thread-safe. In particular:
Each page (or its viewmodel) must be able to subscribe and unsubscribe from the service, which updates the database.
The service updating the database informs all subscribers, that new data arrived and that they should refresh their views.
Obviously, the page, which is just being closed should unsubscribe from the service and the page, which just appears, should (or may) subscribe.
I could put subscription inside a critical section, as well as broadcast about new data, but then imagine the following scenario (page ~= its viewmodel, that does not matter much here):
Service enters critical section to broadcast information about new data (in separate thread)
Page tries to enter critical section to unsubscribe (in main thread)
Service informs page about new data (in separate thread).
Page populates its fields and raises PropertyChange event (in separate thread).
PropertyChange event is marshalled to the main thread. Which waits for the critical section.
And it looks like a deadlock to me.
How can I safely design this architecture to avoid such deadlocks? Maybe pages should never unsubscribe? Or is there another way to secure threads such that they won't deadlock?
Given that the post is tagged WPF and WP-8.1 and the clarification in the comments, i would do the following:
Have the base Model class (the one with properties holding relevant data) implement INotifyPropertyChanged
Have the Model for ALL pages as ObservableCollection<BaseModel>. The model should also implement a mutex/lock property instantiated in the constructor.
Share the model across all viewmodels (e.g. share the instance of the model).
In the 'Service' performing async operation, i would only lock the section of the code that would Add or Remove items from the Model ObservableCollection using the lock object from the Model itself. This section MUST be placed in the Dispatcher.Invoke() or equivalent platform call. This ensures that it is only UI thread that is waiting to update the collection.
I would bind all the UI in the relevant pages to the model reference in the viewmodel.
This way the UI and viewmodels are careless to the specific service events thus eliminating the overhead of subscribing, and you also limit the duplication of the data if you share the model - even with 20 pages on screen, your service will perform a single update that is propagated to the UI and viewmodels by the powers of the framework (binding).
A simple solution could be: Do not do the unsubscribe operation in the UI thread. (In general do not block the UI thread.) Do it in async way, fire and forget.
Alternatively you may take a look to Rx (Reactive Extensions) what are exactly for this purpose: Implementing the observer pattern in multithreaded way.
Silently "just not unsubscribe" is probably not a good idea. Although I do not know your implementation details, if the event handlers are instance methods, then a reference to that instance implicitly will be kept by the service, and depending the reference chain maybe your page or other instances will be prevented to garbage collected.
"Or is there another way to secure threads such that they won't deadlock?" Currently in .NET framework there is no magic trick what automatically prevents deadlock. Other multithreaded environments may or may not provide an automatic deadlock resolution (note: not prevention) service what can detect a deadlock (after it happen) and automatically choose a victim. In .NET it could be an exception what occurs while your are waiting to a resource. (again this is not implemented yet)
Background (Skip this part if you want)
Feel free to skip over this part if you choose, it's just some background for those who want to better understand the problem
At the beginning of one action on my site, I kick off several asynchronous operations. The action returns before the operations are complete. This is what I want. However, the View that gets loaded by this action invokes several other actions in a different controller. Some of these actions rely on the results of the async calls from the first page, so I need to be able to wait on the async calls to finish from the other controller. I thought about just using Session to store the WaitHandles, but as WaitHandles aren't serializable, I obviously can't do that.
Short version:
I need to be able to store an async WaitHandle object somewhere from one controller, such that it can be reliably retrieved in a different controller. These WaitHandles also need to be user-specific, but I can handle that part. Just don't list an option that would make doing that impossible.
I'm currently building a C# application which will automatically authenticate a user against certain network resources when they connect to specific wireless networks.
At the moment, I'm using the Managed Wifi API to discover when a user connects / disconnects from a wireless network. I have an event handler, so that when any of these activities occurs, one of my methods is called to inspect the current state of the wireless connection.
To manage the state of the application, I have another class which is called the "conductor", which performs the operations required to change the state of the application. For instance, when the wireless card connects to the correct network, the conductor needs to change the system state from "Monitoring" to "Authenticating". If authentication succeeds, the conductor needs to change the state to "Connected". Disconnection results in the "Monitoring" state again, and an authentication error results in an "Error" state. These state changes (if the user requests) can result in TrayIcon notifications, so the user knows that they are being authenticated.
My current idea involves having the method used to inspect the current state of the wireless call the "authenticate" or "disconnect" methods within the state manager. However, I'm not sure if this is an appropriate use of the event handler -- should it instead be setting a flag or sending a message via some form of IPC to a separate thread which will begin the authentication / disconnection process?
In addition to the event handler being able to request connection / disconnection, a user can also perform it via the tray icon. As a result, I need to ensure these background operations are not blocking the tray's interactions with the user.
Only one component should be able to request a change of the system state at any time, so I would need to use a mutex to prevent concurrent state changes. However, how I should synchronous the rest of these components is a slight mystery to me.
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
EDIT: Most importantly, I want to verify that an event will be executed as a separate thread, so it cannot block the main UI. In addition, I want to verify that if I have an event handler subscribed to an event, it will handle events serially, not in parallel (so if the user connects and disconnects before the first connection event is processed, two state changes will not be occurring simultaneously).
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
That explains a few things. :)
I would read up on threads, event handling, and creation of system tray icons/interfaces.
It is important to note the following:
Events are processed on the same thread they are called from. If you want the processing of an event not to lock the GUI then you will need to have the button move the work to a different thread.
When an event is fired it passes the appropriate arguments to all the methods in its list. This is pretty much the same as calling one method which in turn calls all the others (see EventFired example). The purpose of events is not to call methods as we can do that already, it is to call methods which may not be known when the code is compiled (the click event on a button control would not be known when the library the control is in is compiled for example). In short, if you can call the method instead of using an event the do so.
void EventFired(int arg1, object arg2)
{
subscribedMethod1(arg1, arg2);
SubscribedMethod2(arg1, arg2);
SubscribedMethod3(arg1, arg2);
SubscribedMethod4(arg1, arg2);
SubscribedMethod5(arg1, arg2);
SubscribedMethod6(arg1, arg2);
SubscribedMethod7(arg1, arg2);
}
If you want to prevent a user interface from locking do the work on another thread. Remember though, user interface elements (forms, buttons, grids, labels, etc.) can only be accessed from their host thread. Use the control.Invoke method to call methods on their thread.
Removing an option from an interface is not a good way to prevent raceway conditions (the user starts a connect/disconnect while one is already running) as the user interface will be on a different thread and could be out of sync (it takes time for separate threads to sync up). While there are many ways to resolve this problem, the easiest for someone new to threading is to use a lock on the value. This way .NET will make sure only one thread can change the setting at a time. You will still need to update the user interface so the user knows the update is occurring.
Your general design sound fine. You could use 2-3 threads (1 for the user interface (tray icon), 1 for checking for new network connections, and 1 (could be merged with connection check) which checks the internet connection.
Hope this helps, let us know if you need more (or accept an answer).
As an option, alternative...
If I were you, and since you're starting anew anyway, I would seriously consider the
Rx Reactive Extensions
It gives a completely fresh look at events and event based programming and helps a lot exactly with the things you're dealing with (including synchronizing, dealing with threads, combining events, stopping, starting etc. etc.).
It might be a bit of a 'steep curve' to learn at start, but again, it might be worth it.
hope this helps,
To me it seems that you're going to overengineer the project.
You basically need to implement an event in Commander and in main application subscribe to them. That is.
If there is always one component can make a change and you can have more then one, using some sync mechanism, like a Mutex noted by you, is perfectly valid choice.
Hope this helps.
If you want to have at most one state change pending at any time it is probably best to have the event handlers of the external events you are listening to hold a lock during their execution. This ensure an easy way to program because you are guaranteed that the state of your app does not change underneath you. A separate thread is not needed in this particular case.
You need to make a distinction between the current state of the application and the target state. The user dictates the target state ("connected", "disconnected"). The actual state might be different. Example: the user wants to be disconnected but the actual state is authenticating. Once the authentication step is completed the state machine must examine the target state:
targetState == connected => set current state to connected
targetState == disconnected => begin to disconnect and set state to disconnecting
Separating actual and target state allows the user to change his mind any time and the state machine to steer towards the desired state.
It's hard to give a precise answer without seeing the whole (proposed) structure of your app. But in general, yes, it's OK to use an event hander for that sort of thing - though I'd probably move the actual implementation out to a separate method, so that you can more easily trigger it from other locations.
The comment about disabling the "Connect" button sounds right on to me, though it's quite conceivable you might need other forms of synchronization as well. If your app doesn't need to be multi-threaded, though, I'd steer away from introducing multiple threads just for the sake of it. If you do, look into the new Task API's that have been included as part of the Task Parallel Library. They abstract a lot of that stuff fairly well.
And the comment about not over-thinking the issue is also well-taken. If I were in your shoes, just beginning with a new language, I'd avoid trying to get the architecture just right at the start. Dive in, and develop it with the cognitive toolset you've already got. As you explore more, you'll figure out, "Oh, crap, this is a much better way to do that." And then go and do it that way. Refactoring is your friend.
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.
Here's what I'm trying to solve:
My class (which could be hosted by an UI app or a windows service or whatever), needs to receive windows messages. Somewhere around here, someone gave the suggestion (and some source code) to create a windows form in a separate thread that will create the form and whenever a windows message that I'm interested in receives on the WndProc, it triggers a delegate using context.Post.
I've been trying to make it work but unsuccessfully. Instead of spending more time on that avenue and before I try to replicate the problem I'm having there to post here for help, I'm thinking I'm going to try to implement the same solution using BackgroundWorker.
From the tests that I've done, I would expect it to work pretty good when I'm using UIs, but my question is: is there any advice against using BackgroundWorker when not dealing with UIs?
Edit:
The way I'm envisioning it, every time my "child" form (the one running in the background worker) receives a message, I will issue a ReportProgress. The only thing that I need to pass through threads is the message ID, so technically it should suffice right?
BackgroundWorker and a window are water and fire. A window requires an STA thread and a message loop, neither are provided by BGW. Check my answer in this thread for an alternative.
I would say if its at most every 5 seconds, then you should be fine passing the message id (as userState) back via the ReportProgress event.
The BackgroundWorker object is an excellent method of performing the tasks you're looking to perform. You may, however, find that a simple message ID is no longer sufficient when you get things coded up, but the BackgroundWorker.ReportProgress method allows you to pass in a state object. If you code up an efficient state object you can literally send back thorough snapshots to report back to the parent form.