In the baseform of a winform project the code for connecting to the database is moved from the load event to the show event.
In the show event there is a call to Update() before fetching data, this makes the form appear much faster which is more pleasant for the users.
But now I found code on some places like this for example :
FormRitDetail ritDetail = new FormRitDetail();
ritDetail.PrimaryKeyValue = ritID;
ritDetail.Show();
ritDetail.SendSaleEmail(cancelSale);
ritDetail.Close();
This worked perfect while the code for fetching data was in the load event, but now it gives an error which I have tracked down. In the SendSaleEmail method the data is not fetched yet.
The fetching happens in the Shown() event, but it seems that c# does the call to SendSaleEmail first, and than the call to Show().
How can I force c# to do the methods in the order as I write them ?
I can do a call to ritDetail.Update() after the ritDetail.Show() I know that, but I would like a general solution that does not involves writing additional code everywhere the show() method is called.
Is this possible ?
In the baseform of a winform project the code for connecting to the database is moved from the load event to the show event.
There is your real problem. You depend on an event to get executed to get into a valid object state. That's called temporal coupling. It's what makes you experience the current problem.
A general guideline is to never execute business logic within events. Instead create separate methods for that. Those methods can in turn be executed from the event handlers.
The other problem is that you need to load and show a form just so send a send email? At least I interpret your question as that the form will just open, execute and close. Move that code to a new class which just that responsibility.
So the answer to your question is:
Do not depend on UI events ensure that business data is loaded. It can be loaded directly but not yet populated into the form until it's ready.
Forms have a UI responsibility. They should not be responsible of business logic. Create separate classes.
Update
Regarding the actual problem, I just checked reference source for the Form class. The Show() method just changes the internal state (using SetWindowLongPtr WinApi function). Thus nothing is done until the message pump processes that message.
There is no guarantee that it's done before the next method call (i.e. SendSaleEmail).
Related
In my Event Sourced System, I have an endpoint that administration can use to rebuild read side Databases in the case of some read side inconsistency or corruption.
When this endpoint is hit, I would like to stall (or queue) the regular system commands so they cannot be processed. I want to do this so events are not emitted and read side updates are not made while rebuilding the data stores. If this happened, new (live) event updates could be processed in the middle of the rebuild and put the read side DB in an inconsistent state.
I was going to use a static class with some static properties (essentially mocking a global variable), but have read this is bad practice.
My questions are:
Why is this bad practice in OO design and C#?
What other solutions can I use to accomplish this class communication in place of this global variable?
Why is this bad practice in OO design and C#? (using global variables)
There is a lot of talks about this on the community, but Very briefly, it makes program state unpredictable..
What other solutions can I use to accomplish this class communication in place of this global variable?
You should not stop the command processing if you only need to rebuild a Readmodel. The Write model should go as usual because it doesn't need data from the read side (unless there are some Sagas also). The clients need the commands to be processed so the rebuilding should be done transparently.
Instead you should create another instance of the Readmodel that uses another (temporary) persistence (another database/table/collection/whatever) and use this to rebuild the state. Then, when the rebuilding is done you should replace the old/faulty instance with this new one.
For the transition to be as smooth as possible, the fresh Readmodel should subscribe to the event stream even before the rebuilding starts but it should not process any incoming event. Instead it should put them in a ring buffer, along with the events that are fetched from the Event store or Event log or whatever event source you are using.
The algorithm for processing events from this ring buffer should be the oldest one is processed first. In this way, the new events that are generated by the new commands are not processed until the old events (the one that were generated before the rebuilding started) are processed.
Now that you have a clean Readmodel that is processing the latest events (a catched-up Readmodel) you just need it to replace the faulty Readmodel somehow, i.e. you replace it in you composition root of your application (Dependency injection container). The faulty Readmodel could be now discarded.
I am using the MVVMLight framework in a metro app. I began by loading data in my ViewModel constructors and everything worked fine. Towards the end of the build I introduced some extra exception handling in the app.xaml.
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
This began to throw a lot of errors about tasks not being awaited properly.
I moved the ViewModel constructor data load calls into my page LoadState method and awaited them there and all works fine. However, I have read that this is possibly bad practice.
Should I introduce an async call to the ViewModel constructor somehow instead? Interested what best pratice may be? Maybe I should remove the exception handler!
A similar question has been asked here:
MVVM view model and async data initialisation
Not sure where you saw that Data call load in LoadState would be a bad practice, in most case you would not even be able to load the data before load state since you would need whatever parameter is passed by LoadState. Also even of the parameter is not needed I personally prefer to load data in LoadState because starting loading it in the constructor mean that you are going to take some of the cpu time while the page is loading so it will take the page a little longer to load. The only reason I see to load it in the constructor would be so that the data is loaded at design time (because the view model cosntructor will be called but not LoadState) but for that you can just add a condition (ViewModelBase.IsInDesignModeStatic) to call load in the constructor for design time
First, a couple of rules:
Ensure that all Tasks are awaited
Never write async void except for event handlers.
That taken care of, check if you still have some errors. Chances are you already had some errors but they haven't surfaced.
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching. For example, if they were going to show a streamreader, they would do:
StreamReader sr = new StreamReader();
..inside the button's click function.
Is this a bad programming habit? From javascript, I remember reading a warning on some code I wrote that said something about creating a function inside a timeout event. Should all variables and objects be declared outside of the button click function?
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching
The reason that putting code inside a click handler would be bad is that a click handler is specifically related to the UI, and the rest of your code might not be.
A stream reader reads from a stream. Code that processes a stream should be grouped with it. Code that handles the fact that you clicked on the UI has nothing to do with reading from a stream, so it should be separated.
Generally you should group your code so that parts of your code that are logically similar are together, and that parts of your code that deal with entirely different things are separated. This will give you "high cohesion". It is related to the Single Responsibility Principle.
Should all variables and objects be declared outside of the button click function?
Absolutely not. If it makes sense to create a specific object when handling a UI event, do so.
However as I mentioned before, if you're dealing with non-UI things inside a UI click handler you're doing too many things at once. Split out your streaming code into another method, another set of methods, or into another object. This will make it easier to read your code, it will make your code have a better chance of being reusable, and it will make it easier to edit your code.
UI logic and flow is notorious for being kludgy and requiring a lot of work-arounds and special handling. It is also the area of your app that you will get the most feedback on, so it will undergo the most change. Everyone will have an opinion on how your UI should work, including non-technical users. If you guard yourself against this by separating your UI logic from the logic in the rest of your app, then those changes will be much easier to make.
You can create instances within your handlers, this is common practice as everything is taking place on the UI thread within your handlers. In addition once the method completes that variable will go out of scope and get marked for garbage collection.
It all depends on how long you need the object to live, if you wont use it outside the button event then it probably should be there so it gets garbage-collected when the event is finished, if you do need to use your objects outside then using a field in your class should be fine.
No it is not a bad idea to create instances in event handlers, but if there is any code that you may want to call multiple places in your code, it is best to that part of code to a separate method instead of trying to simulate button click events
I have small in C# project which has several classes.
The First copies the files, the second synchronizes database SQL CE from SQL SERVER,
and the third is packed to ZIP files etc.
I want to almost every function in these classes repoted to what she did, or failed to do something or not.
At this moment i am so in place when something happened to report it calls
public event EventHandler OperationStatusChanged,
in the StatusEventArgs i pass on the string with a description.
Handling event is in a class that is executing an instance of the class.
Ultimately, I want that all messages, error, etc are stored in the database using Nlog.
It is possible to do it more elegantly than calling event and its handling
Thank you for your time.
Tom
There is nothing wrong in event handling and it is appropriate for asynchronous operations.
However, it looks like your different operations are sequential so your calling class could call them one after the other. To avoid blocking your user interface, start the calling class loop in a separated thread and inform the UX at the end of each operation.
so i have a winforms apps that downloads a set of data syncronously on startup. This obviously takes a while but then when any of the services or GUI classes load, they all have this data. I could change this to put on a background thread but then every component that needs access to this data would continuously have to get notified when this data was ready. This seems like bad design for every one of my classes that depends on this data to be loaded to have a If (Loaded) check or have to subscribe to a loaded event . . . any ideas?
Any other ideas?
I've written a number of applications that have similar behaviour to what you describe, and have three suggestions for you ...
Splash Screen
Add a splash screen to your application that displays the status of a number of startup steps. I've used this in the past when an application has a number of steps that have to occur on startup, before the user gets to use the application - confirmation of identity and authorisation of access through Active Directory, contact database for system information, loading static data, initial contact with specified web services, checking that prerequisites (like Crystal reports) are installed and working, etc etc.
Subscription
Have each component register interest with your data loader, and be notified when the data is available. This is the observer pattern, nothing wrong with it, though managing the subscriptions can be a bit messy.
Lazy Loading
Design the rest of your application to request the data as late as possible, giving as wide an opportunity for background loading to complete as possible. Users who are quick off the mark after startup have to wait for necessary data to load; users who take their time (maybe they started the application and then switched to Outlook) find response is immediate.
I would suggest you use the Observer Pattern and setup all the classes that rely on the data set being loaded. To minimize the amount of time the user needs to wait you could also consider implemented two categories of classes those that need the entire dataset to function and those that can function once a subset of the data has been loaded.
Observer Design Pattern
Everything I do in a desktop app, whether it is Winforms or WPF, I try to do on a background thread. This is done for two reasons. First, the user experience is better. Second, in WPF testing I have found it to be a better performer when loading a lot of data, like records into a grid or list.
Loading data upfront vs lazy loading is really a per-application customization. I would build a central data object that handles both scenarios. The way I might recommend doing this is to create an event driven dependency model. What I mean by this is that you can place an event or callback registration function on a data manager object that various units of code subscribe to when they need to use data, and then they are called back when the data are available. If the data are already available then the callback occurs immediately. Else, the code unit is called back when the data are loaded from a background thread. For example, in some window or component you might have some code that looks like:
DataManager.LoadDataAsync(dataCommandPatternObject, CallBackFunction);
...
public void CallbackFunction(SomeDataObjectClass data)
{
//load data into UI
}
If data loading is done through a central mechanism then if the same data are requested twice, a cache version can be used or the second request can wait if the first request is still running.
If data needs to be loaded up-front, a loading screen (splash screen) can request a number of pieces of data, and when each block of data loads a callback is fired. When all the callbacks have fired, the splash screen exists.
These are just a few points from some various techniques I have used over the years to manage the loading of large data-sets of mostly static/lookup data. On top of all of this, I would also recommend some sort of client-side disk caching for very large datasets that rarely change, and implement some sort of change tracking in the database. This would allow this data to be loaded from local disk by the client, which is faster that going to a DB. It also lets the DB scale better, since it is not serving out data that it highly repetitive, and instead it can focus on transactional data.