0

The Whole GUI is loaded. After clicked on certain button, the GUI is not responsive: any buttons are no response. If I switch to other app and switch back, the GUI is OK immediately. Behind the clicked button, it is a handle sending requests to back end. I debugged app, and data has always been returned. Since the app is huge and I'm not familiar with it, I cannot extract a simple model of sending requests and processing data.I wonder possible causes, since I have no idea now.

Best regards,

-----Add More-----

The back end request sending is in a threadpool thread; when getting data, no UI controls are updated directly. Only presenters (view model) are updated, which are binding to UI control.

Steel
  • 115
  • 2
  • 7
  • We will not be able to help you much without some details. Can you add details about what happens on click on the button? Also, you mention it is a huge app, could there be any processes running on the dispatcher thread which would probably be halted/closed on application lose focus and therefore it seems ok when you get focus back. – Ravi Y Jan 04 '13 at 05:31
  • You are going to have to use a `Profiler` as any answers we give will be guesses – sa_ddam213 Jan 04 '13 at 05:38

2 Answers2

3

I think as sa-ddam213 have suggested and I too believe that you are executing a code block in background Thread or Task.

I think problem is that
- On button click, start execution in background.
- You have kept a flag for checking if background process is running for CanExecute() for the Button's Command.
- UI checks CanExecute() for the Button's Command for a while then does not as mentioned in another question here - Is Josh Smith's implementation of the RelayCommand flawed?.
- Process returns in background.
- UI does not knows the background process is completed and as it has stopped checking the CanExecute() for the Button's Command, UI will not come to know itself.. (you need to tell it)
- Therefore UI is not responding but when user will click somewhere in the application or do an in-out as you said, it will back again.

Solution
- By using InvalidateRequerySuggested method you can invoke the command requery on UI thread so UI will recheck the CanExecute() for each Control and/or Button Command.

// Forcing the CommandManager to raise the RequerySuggested event
CommandManager.InvalidateRequerySuggested();

The InvalidateRequerySuggested method forces the CommandManager to raise the RequerySuggested event. The RequerySuggested event informs a command source to query the command it is associated with to determine whether or not the command can execute.

For more refer:
- How does CommandManager.RequerySuggested work?
- MSDN - CommandManager
- MSDN - CommandManager.InvalidateRequerySuggested Method

Community
  • 1
  • 1
Harsh Baid
  • 7,031
  • 5
  • 44
  • 87
  • Do you mean the CanExecute() is released by GC as [here](http://stackoverflow.com/questions/2281566/is-josh-smiths-implementation-of-the-relaycommand-flawed), so UI stops checking? – Steel Jan 04 '13 at 09:42
  • Have you tried executing `CommandManager.InvalidateRequerySuggested();` on UI Dispatcher instance after the background process finishes.. ? – Harsh Baid Jan 04 '13 at 10:39
  • I tried but didn't work. ` var syncContext = DispatcherSynchronizationContext.Current; if (null == syncContext) syncContext = SynchronizationContext.Current; syncContext.Post( (state) => { CommandManager.InvalidateRequerySuggested(); }, null);` – Steel Jan 06 '13 at 05:33
  • I think try using Dispatcher this way to invoke the CommandManager `Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { //some code });`. And do post your findings or solution, if any you have found.. :D – Harsh Baid Jan 07 '13 at 05:09
  • Your suggestion is not work for my case, but it opens my eye and useful. The cause in my case is a fault of existing styles; my new adding conflict with it. I will add more detail later. Thanks. – Steel Jan 07 '13 at 08:25
1

Its just a wild guess but try dropping the priority of the logic inside your click event

Example

private void Button_Click(object sender, RoutedEventArgs e)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)delegate
    {
        // all your code here.
    });
}
sa_ddam213
  • 39,994
  • 7
  • 93
  • 106
  • Possibly is it not even done async with a begin invoke and hence the dispatcher thread is just busy and blocked. – Ravi Y Jan 04 '13 at 05:48
  • The back end request sending is in a threadpool thread; when getting data, no UI controls are updated directly. Only presenters (view model) are updated, which are binding to UI control. – Steel Jan 04 '13 at 07:47