lets say you are adding a feature to an old and running windows form application now the whole application is running in one thread and the application is really big and have many forms so you cant refract it to run in multithreads, now the application gui freeze everytime you make a process , is there is any way to have an indicator that its loading or in progress while its freezing ? without changing the whole design of the software to support threads etc ?
by the way i dont want it to stop freezing its ok to freeze i just want it to to indicate that its doing something !
any idea would be appreciated, thanks...
See BackGroundWorker componet if application is written using .net 2.0 or higher version.
You can set the form's Cursor property to Cursors.WaitCursor upon starting the long running action, and reset it to Cursors.Default upon finish. While your action executes you can call Application.DoEvents() but it may cause side effects if other events trigger in the mean time.
Related
I'm developing a Revit add-on which performs some lengthy tasks. During the process, I want to display a simple WPF window with an indeterminate progress bar, a label to inform about current process and a button to enable aborting.
I already tried the most obvious ways of accomplishing that: creating a WPF window inside the add-on and displaying it, but the problem is that the UI gets frozen, no matter how I implement this. During some processes, the whole Revit UI gets frozen/white so I really wouldn't expect my embedded WPF window would behave normally in these conditions anyway.
The workaround I figured out was to have the WPF window as a separate app (EXE file) I could run from the add-on. I based my implementation on this example .
The good part of it is that it doesn't hang no matter what is happening with Revit.
The bad part is that the sequence of how Windows is queuing the calls of my separate WPF app is sometimes different from the sequence of these calls from my add-on. It sometimes results in a situation when the Revit process is over but the WPF window is still displayed (waiting for the final, closing call which had been apparently already executed, but then the app got reactivated with another, delayed call).
Preferably I would like to handle the WPF app the same way as you can i.e. handle an Excel application from .NET. You create an ExcelApp object, do what you want with it and dispose of in the end.
The problem is I don't have a clue of how to do this.
How should I expose the WPF app's API to my add-on?
Could it be possible to have the WPF app responsive and controlled from the Revit add-on at the same time? (user can still click the abort button, the indeterminate progress bar doesn't freeze)
The First thing to know is about interacting between two processes. there are some Standard approaches:
Interacting through Socket (Socket Programming)
Using Named PipeLines (Useful when your messages aren't so long)
There are some other predefined Libraries based on above techniques. Using a FileSystem Based method is not a reliable way to proof the outputs.
This was a part of your solution. The next step is to use Threading in your WPF application. I'm not familiar to Revit and I don't know how it works.
UI freezing is normal in a long running process. because UI is busy and it can't answer your requests (e.g Mouse Move, Click, ...). So using a Thread you can put your long running process into a separate place and wait for the response at the end of it.
There is a problem while using a Thread. Because you left your UI and started your long running process on a separate Thread, you can't directly access to your ProgressBar. In this situations you have to use ThreadDispacher. It's not a terrifying concept, it just a three line of codes that will adds to your callings.
for example:
Dispatcher.Invoke(() =>
{
ProgressBar.Value++;
});
Search for a Library to doing your IPC (Inter Process Communication) to get the result faster (or you can learn about above techniques to do it by your means) and next add a simple thread to your WPF application so you be able to Start, Pause and resume the running job based on the situation.
so I've been seeing applications run in the background in the task manager, but when I create an application it displays in the apps section(here's what I mean):
But here is what I would like to achieve(to make it a background process):
Thanks, all help is appreciated!
Honestly I do not think this is possible using normal development methods. I mean it's a form, it cant run in the background because it has a user interface. Why do you think you need to run a form in the background anyway?
Just spit balling here: Maybe you can implement just the actions you need in a Background process thread that is created in the form, then close the form. If the form runs in its own thread, perhaps you need to set the priority on the thread lower.
I am trying to make a windows form appliation that displays all the Tasks that are running while they are running. I want to stop tasks individually if I want to. I have the application working as a console application but when I try to build it as a windows form application it screws up. Here is how my code works.
Loop
Make a task
store it in a list
start the task=
End Loop
I want to display this list in a listView in my form and update it every few seconds displaying the name and status of this task.Can somebody help me with that or suggest good reads to study multithreading.
Thanks.
I have the application working as a console application but when I try to build it as a windows form application it screws up.
Provided that you didn't change your logic during the port to Windows Forms, this is likely due to updating the Windows Forms controls from the background thread within your Task.
You can only use Windows Forms controls from the main (UI) thread, and not from a background thread. If you want to perform an update to the UI, you need to use Control.Invoke or Control.BeginInvoke to marshal the call back onto the UI thread.
I have a console application that shows latest activities & status on its console. The application is heavily threaded & performance is the major concern. No user interactivity is required. Due to a recent case, ive been asked to migrate it to a win form application.
Initial post ->
How to programmatic disable C# Console Application's Quick Edit mode?
So to encounter the problem, I have used Application.Run(ApplicationContext context) so to start a message loop in my console application so that i can hook and trap mouse events and can reset quick edit mode at runtime. I have also deleted a Console's default menu item "Edit" that emerges on right click so not to allow the user to Mark/Copy/Paste.
I want to know what should be the optimal solution, migrating to win form or console app (considering changes i made). Also i need to call Invoke every time in order to put the task in UI's queue so to print the message if migrated to winform.
WinForms would definitely give you more flexibility in what you can do with the UI.
In terms of performance, you really need to be doing a lot of UI updates in order for performance to be a concern. It sounds like that will not be the case since you're currently getting it done with a console application. Most of the time, the UI performance is affected not because the UI thread can't keep up with the updates, but because non-UI stuff (e.g. file IO, database queries, etc.) is done within the UI thread.
I would consider to change your application so that it streams it's output into a logfile, a lightweight database or a Windows event log instead to the console. Thus your application won't need a console or UI at all and can be alternatively run as a service. If someone wants to see that messages, give him a separate (probably Winforms) program to view the latest output, or if you use the Windows event log, he can just use the Windows Event viewer to check the output of your program.
So you neither have to migrate you application to Winforms, nor do some ugly console hacks.
To process log files, the Microsoft log parser may be of interest for you.
I am now developing an application on Windows Mobile 6.5 with .Net Compact Framework 3.5 using C#. There is a function in the program that I use it to update the location information periodically from server side, but if I keep running this computation, it would cost too much energe. For this reason, I want to run it in background and I try to use BackgroundWorker to do this and it works well.
The problem I have now is that I can't minimize the program so that I have to keep the main form of the program run in foreground even if it's not doing anything and this is very inconvinence for a user. However, when I close the program, the BackgroundWorker will also be closed.
Is there any method to keep the update process running (somewhere in memory or so) when I close the program? and then can restore the information when I restart the program?
How about creating a Service instead of a background worker?
If your Form closes, then Application.Run (probably called over in Program.Main) returns and the process' primary thread exits, causing the application to terminate.
The solution, then, is don't close the Form, simply Hide it. By default the "MinimizeBox" property for your Form should have been true and it should have an [X] in the upper right corner. Clicking this minimizes the Form and will not exit your application.
The other option in some cases is to not have a Form at all. The challenge here is that the CF doesn't have any Application.Run overload that doesn't accept in a Form (like the desktop framework does). The Smart Device Framework does provide one if you want to go that route.
I have not used the .NETCF 3.5. However in the previous version on .NETCF 1.0/2.0 I observed that even if you close the application using (X) button, it just goes to background but remain in the memory.
If that is the case with .NETCF 3.5 as well then I think you do not need to anything here. The background worked will be running even if you close the application.
I Hope this will help you.