Caliburn Micro window freezes when clicking button

Viewed 41

I'm completely new to MVVM and Caliburn Micro. I had a program where the code was "behind" the MainWindow. I wanted to make it more responsive so I decided to try to use MVVM. The problem now is that when I click a button to start the program the whole window freezes, even the button stays in the clicked state. The program may take 30 minutes to run and regularly updates a log(TextBox) about the process but this is not seen until the program exits. I'm sure there is a simple fix for this, but I'm too new to this to figure it out. I've tried using CM 3.2 and 4.0.

Some code:

<Button Content="Do panorama" cal:Message.Attach="[Event Click] = [Action Panorama($source)]" Tag="PanDo"/>

public void Panorama(Button button)
{
 // some code 
}

public string PanLog
{
    get { return _panLog; }
    set { if (value == "") { _panLog = ""; } else { _panLog += DateTime.Now.ToString("yyyy-MM-dd - HH:mm:ss") + " : " + value + "\n"; ; } NotifyOfPropertyChange(() => PanLog); }
}



1 Answers

The typical reason for such a behavior is that the UI thread is blocked. This means the application does not respond to user input, is not updated, and may show an windows error message about being unresponsive.

The typical approach is to use asynchronous programming techniques. If your application is blocked due to doing a bunch of computing:

public async void Panorama(Button button)
{
   try{
      await Task.Run(PanoramaImpl);
   }
   catch{
      //handle failure
   }
}
public void PanoramaImpl(){
    // actual work
}

If your work is IO limited you would instead use async-version of any IO-calls and await these instead of using Task.Run.

Note that this means your program will use a background thread for all computations, and you cannot update the UI from a background thread. So you should use some form of progress reporting, and possibly also use a cancellation token to let your user abort the operation.

You may also consider showing a modal dialog while the process is working, to prevent the user from doing anything else in the UI, or clicking the same button multiple times.

Related