Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make wpf UI responsive when button click is performed

In my wpf (c#) application , a long process is performed when a button is pressed by the user. When button is pressed until the complete code executed the window freezes and user cannot perform any other task in the window. How can I make the button click code as a background process, so that the window become responsive to the user. I have tried the following method, but was unsuccessful.

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
    new Action(() => { 

         WorkerMethod();
    }));
}

Where WorkerMethod is the function with the entire code. Any suggessions.

Regards,
Sangeetha

like image 648
Sangeetha Avatar asked Mar 14 '13 12:03

Sangeetha


3 Answers

If you are targeting .NET 4.5, you can use async/await to make your UI responsive:

private async void btn_convert_Click(object sender, RoutedEventArgs e)
{
    await WorkerMethod();
}

Modify your WorkerMethod:

private Task WorkerMethod()
{
    return Task.Run(() =>
        {
           // your long running task here
        });
}
like image 182
Oliver Avatar answered Sep 27 '22 20:09

Oliver


What you have actually done here is asking the UI thread to run your heavy task through the Dispatcher.

You should create a new thread/Task and let it run your background Method:

Thread t = new Thread(() => WorkerMethod());
t.Start();

for further information read this:

WPF BackgroundWorker vs. Dispatcher

Understanding “Dispatcher” in WPF

like image 45
makc Avatar answered Sep 27 '22 18:09

makc


An alternative to the answers here is a BackgroundWorker. It has the added benefit of returning you to the GUI thread after it's done.

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += WorkerMethod;
    worker.RunWorkerCompleted += WorkerEnded;
    worker.RunWorkerAsync();
}

private void WorkerMethod()
{
    // New thread, cannot access GUI
}

private void WorkerEnded()
{
    // Back on the GUI Thread
    // Worker is finished
}
like image 20
AkselK Avatar answered Sep 27 '22 19:09

AkselK