2

as much as we know, programs are executing line by line, and now I am facing issue, I have a method which is taking few seconds to execute, I thought I could solve it by threads but I will speak about it later, now what I would like to do is next:

How could I open a window with message like "Still executing..." when that method start execution and when method is done window could close himself, I need that because I Would like to avoid UI freezing because that long method is not in another task/thread.

Here is how it looks like:

if (e.Key == Key.Delete)
{
    //Could I show window here like like "Loading please wait.."
    ExecuteLongMethod();
    //When this is done close this method
}

Thanks guys, Cheers

billy_56
  • 649
  • 3
  • 11
  • 27

3 Answers3

2

If your ExecuteLongMethod() must be executed on the dispatcher thread for some reason, you could create a new window that launches in a separate thread and display this one during the time it takes for the long-running method to complete. Please refer to the following link for more information.

Wait screen during rendering UIElement in WPF

The other option would otherwise be to execute the long-running method on a background thread and display the loading window on the main thread.

The recommended way to do this would be to use the task parallel library (TPL) and start a task: https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx

if (e.Key == Key.Delete)
{
    Window window = new Window();
    window.Show();

    Task.Factory.StartNew(() => ExecuteLongMethod())
    .ContinueWith(task => 
    {   
        window.Close();
    },System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
Community
  • 1
  • 1
mm8
  • 163,881
  • 10
  • 57
  • 88
  • what does System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); means? and is it possible that this can stay somewhere in processes or wherver, somewhere out of my application? – billy_56 Mar 30 '17 at 12:30
  • TaskScheduler.FromCurrentSynchronizationContext() makes sure that the ContinueWith delegate (window.Close()) gets executed on the UI thread: https://blogs.msdn.microsoft.com/pfxteam/2009/09/22/taskscheduler-fromcurrentsynchronizationcontext/. System.Threading.CancellationToken.None and TaskContinuationOptions.None are default arguments that gets passed to the ContinueWith method. – mm8 Mar 30 '17 at 12:33
  • is this what is called threading? or ? I am gonna read link you provided right now, you are great and awesome, thank you mm8 – billy_56 Mar 30 '17 at 14:47
  • Yes, the Task.Factory.StartNew creates and starts a task that is eventually being executed on a thread pool thread using the default TaskScheduler. – mm8 Mar 30 '17 at 14:49
1

An example where a top window/control is displayed with progress information and the main window is disabled:

if (e.Key == Key.Delete)
{
    // create a window with a progress ring or progress bar
    var window = new Window();

    new Thread(() =>
    {
        // execute long method
        ExecuteLongMethod();

        // close the progress window - release control
        // ensure it is done on the UI thread
        System.Windows.Application.Current.Dispatcher.Invoke(() => window.Close());
    }).Start();

    // display progress window
    window.ShowDialog();  
}

Another approach would be to temporarily disable or hide any UI elements (buttons, tabs) that might interfere with the background thread and do not block the main window.

Krzysztof Bracha
  • 903
  • 7
  • 19
0

Use the await-pattern

    public void YourMethod()
    {


        if (e.Key == Key.Delete)
        {
            //Could I show window here like like "Loading please wait.."
            FireAndForget();
            //When this is done close this method
        }
    }

    public async void FireAndForget()
    {

        await Task.Run(() => { ExecuteLongMethod(); });

    }

Fire and forget is an antipattern so, but sometimes u face problems where you cant await forever - like in Commands.

If you want to wait for a Result or till its finished go like this

public async void YourMethodAsync()
{


    if (e.Key == Key.Delete)
    {
        //Could I show window here like like "Loading please wait.."
        await CorrectWayAsync();
        //When this is done close this method
    }
}



public async Task CorrectWayAsync()
{
    await Task.Run(() => { ExecuteLongMethod(); });
}
Peter
  • 1,655
  • 22
  • 44