Вы можете использовать BackgroundWorker , который прост в использовании.
Кроме того, я не уверен, что совершенно безопасно (хотя я могу ошибаться) показывать SaveFileDialog в новом потоке. Моя рекомендация будет такой:
- Показать SaveFileDialog в главном потоке.
- Передать имя файла методу, который затем вызывается асинхронно.
Вот пример реализации, без использования BackgroundWorker
:
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = "C:\\";
sfd.Filter = "All files (*.*)|*.*";
sfd.FilterIndex = 1;
sfd.RestoreDirectory = true;
if (sfd.ShowDialog() == DialogResult.OK)
{
// Invoke the SaveFile method on a new thread.
Action<string> invoker = new Action<string>(SaveFile);
invoker.BeginInvoke(sfd.FileName, OnSaveFileCompleted, invoker);
}
}
protected void SaveFile(string fileName)
{
// save file here (occurs on non-UI thread)
}
protected void OnSaveFileCompleted(IAsyncResult result)
{
Action<string> invoker = (Action<string>) result.AsyncState;
invoker.EndInvoke(result);
// perform other actions after the file has been saved (also occurs on non-UI thread)
}
Обратите внимание, что все действия, выполняемые с потоками без пользовательского интерфейса, должны влиять только на элементы без пользовательского интерфейса. Если вы хотите изменить элементы пользовательского интерфейса, вы должны перенаправить обратный вызов в поток пользовательского интерфейса, используя Control.Invoke
(например, this.Invoke
). См. этот пост для получения дополнительной информации.