I have very generic question. I tried google it but couldn't find anything good.
So the question is: I have winform application where based on option selected from menu bar, child form/view is loaded and these child forms are used to display reports.
in order to generate report, these child form contains report selection criteria like date, name etc and these value comes from DB. based on values available in DB, we add controls in the view.
Problem comes when screen takes lots of time to load, it freeze UI/application during loading that I don't want.
I also tried run tasks async but since it is using view during the processing, this option failed.
ThreadPool.QueueUserWorkItem(delegate { method.Invoke(presenter, results); });
presenter is my viewpresenter and results is parameters to invoke it. application concluding presenter name at run time and calling its default method using methodinfo.invoke().
Is there any other way to achive the same.
Point: I cannot redesign the whole application to separate out complete DB logic from UI logic as it is legacy application and this might break the application.
If "freezing" is the problem, you could use doevents, see here: Use of Application.DoEvents()
Or, you could go the really old fashioned, vb6 way: run the code that freezes your UI synchronously, but from a modal window shown above your ui. You can event present the user with the progress indicator.
Related
I'm updating a very large Windows Forms app to .Net Maui to make it into a cross platform app. Ideally, I would have the time to rewrite everything, but I don't. The client wants it yesterday. I'm already using a ton of the allotted time replacing the Windows Forms style interface with the XAML version. I've tried not to tinker too much with the code since the app was behaving flawlessly. Still, I've had to make a lot of changes because the Maui controls aren't always accessed the same ways as Windows Form's controls. Almost all of the methods and functions in the original app are synchronous. But some of the .Net Maui functions that I use to replace them are asynchronous. One function that is giving me a lot of trouble is the awaitable DisplayAlert(). Execution moves right onto the next statement in the code without waiting for the alert to be displayed or the user to respond. The function can be made awaitable, but to do this, the entire method within which it appears must be marked Async, which creates its own problems. There are literally hundreds of calls to The Windows Forms version of DisplayAlert(). Any solution that isn't basically a drop in replacement is going to cost tons of time.
I've been trying to create a blocking popup function that waits for the user's response before executing the next line of code within a synchronous block of code. In the XAML markup I've defined a popup "panel" with a frame, two labels and 3 buttons. Ideally, the code behind should be a function with the same parameters and behaviors as DisplayAlert() except that it blocks. It should display the panel, wait for a user response (button click/press), hide the panel, and finally return the text string of the button that was clicked...all within the same function.
Using simple method's like while loops to determine if a button was pressed block the thread from detecting that a button was press. Moving the panel display to a different thread than the button press, does nothing since the panel can only be displayed on the main thread. Invoking on the main thread has not been successful...at least not the way I wrote the code. I'm hoping someone can provide a very simple example of a blocking DisplayAlert() function that can be used within a non-async method.
My app consists of 3 tabs, each tab has a DGV, tab 1 and 2 do not contain that much data within the DGV but in tab 3 it can be between 100-5000 rows
The problem im having is that when i start my app, and move to tab 3 it takes a while before anything is displayed..
Im looking for a way to display a loading form to the user while the data is being added to the DGV..
How would i accomplish something like this?
Start loading data on a background thread and monitor the progress(displayed as progress bar).If you are doing it on main thread than you'll hang your interface.
Theres one good article but it is in VB.
Long running operations should be running in a seperate worker thread, commonly BackgroundWorker class. This prevents the UI from locking up during said operation. You can also choose to display a loading dialogue while this thread runs.
The other answers here are correct. But since you specifically asked about a loading window, I remembered a very nice example in Code Project.
In a project I was involved with, we took this example and made it independent. We added static methods called Start and Stop, and the Start method would create a thread, and then load the window, while the Stop method signaled the form it needs to close gracefully.
Hope this helps!
Sorry if the title is a bit nondescript, I couldn't really word it right.
Basically, what I have is the following scenario:
I have a user-interface (WinForm) that allows users to pick multiple files to download, and then hit the "Download" button to commence downloading. All the downloads are processed asynchronously to avoid locking the form. However, while I don't want the form to lock up with a "Not Responding" message, I also don't want the user to be able to modify form fields while the download is running.
Ideally, I wanted to spawn a modal dialog which let's the user know the state of the download (i.e similar to firefox, except with a modal dialog). This kills 2 birds with one stone as it allows the user to get a good view of the download progress, while also stopping the user interacting with the parent form while the dialog is active.
However, to properly give the user an idea of the download progress I'd need to update the dialog during runtime. This is where I've hit a wall. My current idea is to expose some public methods of my dialog class to send it updates when files complete, and call them from within the background download thread (with proper delegates to update controls, etc)
I'm pretty sure this would work as I want, but I was just wondering if there are any more elegant solutions to this problem. Don't feel limited to the dialog approach, I'm open to all approaches that may offer a better alternative.
Cheers,
J
Alternative 1
You may consider using a BackgroundWorker, it will take of setting a new thread to do the job and provides an event based mechanism to report progress and also a method to request to cancel the operation (it is up to you if you want to use that).
To set the task for your BackgroundWorker you will need to attach a handler to the event DoWork and then call RunWorkerAsync().
Alternative 2
Another alternative is to use IObservable<T> to create a mechanism to respond to the progress of the download, then you could do the binding with using Reactive.
I take you are new to Reactive. In that case, this is best introduction available (in my opinion):
http://channel9.msdn.com/Blogs/codefest/DC2010T0100-Keynote-Rx-curing-your-asynchronous-programming-blues
If you had the freedom to not disable the UI... You could have the progress reported at a status bar, or dedicate a secondary form (which you could let the user close and get back with a NotifyIcon) where you have the current and any pending works.
In an application that I'm writing I have to load a lot of data in a listview after I push a certain button. Because this might take a while, I want to show a simple loading-screen to the user.
I did this by creating a very simple form with 1 label on it. I do a Form.Show() before I start fetching the data, and a Form.Close() once it's finished. This works partially: I get the loading screen, it closes at the right time, but as you can see the label isn't displayed.
I know I should program this loagind screen-problem with the help of a BackgroundWorker, but I'm not a very experienced C# programmer so if I could just somehow force the label to display I would be more than happy.
Is it possible to force this label to display immediately, or do I have to find another solution?
The UI Message pump has no time to update the label / refresh the screen since the loading process takes up all resources.
You can try to force the update of the label, by calling Application.DoEvents(). Although, using 'Application.DoEvents' is imho a 'code-smell', and thus indicates that the design is not that good. So, it should be avoided.
Therefore, using DoEvents is surely not the best solution to this problem. It is merely a symptom-fix.
You've mentionned the best solution already yourself: use another thread to load all the data. (You can indeed use a BackGroundWorker for this purpose, since this will abstract away a lot of plumbing code).
BackgroudWorker is very easy to use , even c# is very powerful and simple langugage
See Here
i am almost sure that , you would not need any more help with BackGroundWorker but if you have any query , you canm always post on SO ?? Collabartive Intelligence is what SO is?
I have a WinForms application written in C#. The first screen to appear when it opens is a dashboard screen that can take some time to load. The data loading method is called using BeginInvoke on delegate. That part is fine, my problem is when I want to load the read data into some grids. The code to get me back to my UI thread looks like so
BeginInvoke(new Action<DashboardDataInfo, int>(LoadDashboardData), data, outbox);
This all happens without error. My problem is the dashboard Form will jump to the top of the screen. If data loading has taken long enough the user could be already onto another from in the app (so this is really annoying). The LoadDashboardData method doesn't do much besides assign the DataSource property of a few DataGridView controls.