CBreeze
CBreeze

Reputation: 2973

Displaying Please Wait Window on a SeperateThread

I have a method that exports the contents of my DataGrid to a CSV file. I'm trying to display a Window that has an animation on it to ask the user to wait.

However, when I show the Window the animation freezes so I assumed that this is because as the excel method is running on the same thread it freezes.

What I have tried so far is this;

var waitWindow = new PleaseWaitWindow();

var newWindowThread = new Thread(() =>
{
    waitWindow.Show();
    System.Windows.Threading.Dispatcher.Run();
});

newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();

ExcelExport();

waitWindow.Close();

but this leads to an error;

The calling thread cannot access this object because a different thread owns it.

How can I start a new thread so that the animation does not freeze whilst the excel method is exporting?

Upvotes: 0

Views: 398

Answers (1)

Manfred Radlwimmer
Manfred Radlwimmer

Reputation: 13394

You need to move the creation of the window into the new Thread, use ShowDialog to make sure it blocks and close it via its own Dispatcher.

PleaseWaitWindow waitWindow = null;

var newWindowThread = new Thread(() =>
    {
        waitWindow = new PleaseWaitWindow();
        waitWindow.ShowDialog();
    }
);

newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.Start();

ExcelExport();

waitWindow.Dispatcher.BeginInvoke(new Action(() =>
{
    waitWindow.Close();
}));

Just make sure waitWindow is created before trying to close it, some kind of IPC barrier would be good here. For Example (quick and dirty):

PleaseWaitWindow waitWindow = null;
AutoResetEvent loaded = new AutoResetEvent(false);

var newWindowThread = new Thread(() =>
    {
        waitWindow = new PleaseWaitWindow();
        loaded.Set();
        waitWindow.ShowDialog();
    });

newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.Start();

ExcelExport();

loaded.WaitOne();

waitWindow.Dispatcher.BeginInvoke(new Action(() =>
{
    waitWindow.Close();
}));

Upvotes: 1

Related Questions