wings
wings

Reputation: 801

SaveFileDialog doesn't show in new thread?

I've been confused by this problem for a very long time. I start the new thread by using System.Threading, just like this:

ParameterizedThreadStart threadFileExport = FileExport;
Thread threadExport = new Thread(threadFileExport)
{
    IsBackground = true,
    Name = "threadExport",
    Priority = ThreadPriority.AboveNormal
};
threadExport.Start(_dataTable);

and

public void FileExport(object objTable)
{

     SaveFileDialog saveFileDialog = new SaveFileDialog
     {
         DefaultExt = "xlsx",
         Filter = "Excel 2007-2010|*.xlsx|" +
                  "Excel95,97,2003|*.xls|",
         FileName = "table.xlsx",
         Title = "Save as. . ."
     };
saveFileDialog.ShowDialog();
}

But the dialog won't show and it seems that the thread will abort immediately when executing "ShowDialog". Is this a bug or I made a mistake? Can a background thread shows a savefile dialog?

Upvotes: 1

Views: 4139

Answers (2)

henginy
henginy

Reputation: 2071

The thread you created doesn't establish a message loop, so you cannot show it.

Better is to ask user the file path on the UI thread and then start your export thread, passing it the file name. Still better is using a BackgroundWorker thread so that your UI remains responsive.

Update: If you cannot use BackgroundWorker, below is the code for the alternative I described. I assume you have a method similar to ExportDataTableToFile which you call after you get the file name.

//
// Assuming your actual export method is similar to this:    
//
void ExportDataTableToFile(DataTable dataTable, string fileName) {
    // ...
}

And I assume you're on the UI thread here:

//
// You can ask for the file path first;
//
SaveFileDialog saveFileDialog = new SaveFileDialog
{
     DefaultExt = "xlsx",
     Filter = "Excel 2007-2010|*.xlsx|" +
              "Excel95,97,2003|*.xls|",
     FileName = "table.xlsx",
     Title = "Save as. . ."
};
saveFileDialog.ShowDialog();


string fileName = null;
if(saveFileDialog.Result == DialogResult.OK) // "else" case should be added
    fileName = saveFileDialog;

//
// And then start the thread:
//
Thread threadExport = new Thread(() => ExportDataTableToFile(_dataTable, fileName))
{
    IsBackground = true,
    Name = "threadExport",
    Priority = ThreadPriority.AboveNormal
};
threadExport.Start();

Upvotes: 2

ekholm
ekholm

Reputation: 2573

No, a dialog must be shown on the UI thread, just as any other UI operation.

Upvotes: 6

Related Questions