I have a page that runs a large amount of code to prepare the page and layout of the page for the user.
It only needs to be used once in a blue moon. But when it does, it's about three seconds of wait for the user.
Apparently, Microsoft only allows a 2 or less second wait. Daaaaang.
I've optimized and optimized the code, and there's no way around it: the code is as fast as it can be. So naturally, I set out to make a loader.
I tried to update several controls, but thanks to the UI thread being frozen, they didn't work.
I searched and searched and searched, and found this, which was confusing and didn't really help, partly because of WP7's version of C# and partly because of me being a beginner at C#.
How can I make a loader that works while the UI thread is frozen?
The Silverlight Toolkit For Windows Phone introduces the PerformanceProgressBar, "which uses the compositor thread exclusively for animation, instead of the UI (user interface) thread" as described in this WindowsPhone Geek article. This should help you with the freezing UI.
As of the parallel execution (suggested by Merlyn), I'd suggest the QueueUserWorkItem method to execute code in a separate thread over the BackgroundWorker, leaving the UI thread active for UI updates, but as described in the article, you will need to use Dispatcher.BeginInvoke to update your UI from there.
You can try using the BackgroundWorker class. That page has a tutorial for how to use it.
See this question and my answer for another tutorial. Though not Windows Phone 7 specific, it still has to do with updating the UI while waiting for a task to complete:
How To Load UI Independent Of Data
Here's a Windows Phone 7 specific tutorial for using the BackgroundWorker:
http://blogs.msdn.com/b/priozersk/archive/2010/09/20/creating-progress-dialog-for-wp7.aspx
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.
When a browser is opened, before it's completely loaded, we can use the controls as others are being loaded (the address bar appears and, while the bookmarks are loaded, we can already type in it).
I'm making a personal browser, and I don't know how to perform that. I imagined creating the controls in another thread, but soon I discovered that that's not possible.
In my last question (where I discovered the above), I received an answer talking about Attribute, Reflection, async/await modifiers and observable collection as the closest solution to that and I'll study them yet. In this new question, I would like to receive others suggestions of how that could be made (allow the user to use the window and controls while others are being created/loaded).
Thanks in advance.
Actually I believe the process of loading the UI part of controls isn't the heavy one.
In the other hand, loading the data which is later bound to the control is the problem.
You can't draw controls outside UI thread, but you can load heavy data, preload resources or do calculation in a background thread.
While heavy controls' data is prepared to hit the UI in some background thread, UI will still be responsive.
For example, I guess Web browsers do HTML to DOM parsing in a background thread and they stream results in real time to the UI thread. That is, address bar and other UI components are responsive because UI thread isn't stressed.
I have something working but I'm not sure it is OK and if it will cause problems later on.
I have a Win32 C++ app which does some video processing and uses Direct3D for display (not my code). My task is replacing the GUI with a C# GUI.
I've made the C++ code into a dll.
I've created a GUI in C# and have a panel intended for the video-display. I pass this panel's HWND to the dll, and everything seems to work just fine.
But - that panel is being accessed by a thread other than the one it was created on, which shouldn't be done.
Part of me wants to "leave well enough alone" but this feels wrong and I suspect it will cause problems down the line. Such as when we want to catch click-events on the panel, which will be on the main or UI thread ... which created the panel.
ANy suggestions on how I should be doing this?
Thank you
Thanks
I think you already know the answer to this. Windows have thread affinity. All operations on a window should be performed from the thread that created it.
Given this rule, I can't imagine that the DLL is responsible for moving window access onto a different thread and presume it is your code that does it. The solution is for you to create and access the window in the same thread that calls the DLL.
The main problem I've seen with this technique is that your UI can flicker. If you are early enough in the process to use WPF you may want to take a look at D3DImage if not what you are doing now will mostly work.
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.
I recently started programming in WinForms using C#. I have a requirement where I need to search a set of folders and the sub-folders and display the status information to a textbox as I do the search like -
Looking up folder "C:\Windows"...
Found 8 files...
Copying file 1 of 8 to "D:\Temp"...
I have a method which does all the searching and stuff. I don't know how to display the status messages (like above) to a textbox periodically. Currently, the form waits for the method to be complete, and displays the messages all at once. I want them to be displayed one by one as the method progresses.
Thanks in advance.
To properly solve this your searching function will need to be running on a background thread. If the searching occurs on the UI thread it will block updates to the display preventing a periodic status message from being displayed.
The easiest way to do this in a WinForms application is to use a BackgroundWorker. It has a minimum of support for running a task on a background and returning progress information to the UI thread. Additionally there are a lot of tutorials available online to get you started with a solution.
use a BackgroundWorkerThread and the ReportStatus function. That way your UI will be responsive while the search takes place.
Run the method that performs searches on a separate thread (if you're not doing so already). It's quite easy using the async delegate features in .NET.
You can then write to the text box from the worker thread using Control.BeginInvoke() - you must do this because access to UI control sis affinitized to the single UI thread.
You can also create a background worker thread and use the ReportProgress method to notify the UI of updates. There's a fairly complete example of this approach available here that you can download and examine.