Ответ 1
ShowDialog() не следует вызывать из фонового потока - используйте Invoke (..).
Invoke((Action)(() => { saveFileDialog.ShowDialog() }));
При вызове saveFileDialog.ShowDialog()
в фоновом потоке я получаю следующее исключение:
Текущий поток должен быть установлен на один (STA) до OLE звонки могут быть сделаны. Убедитесь, что ваш Основная функция имеет STAThreadAttribute отмеченные на нем.
В соответствии с этим:
Чтобы устранить проблему, вставьте утверждение:
Threading.Thread.CurrentThread.ApartmentState = Threading.ApartmentState.STA;
в правом верхнем углу перед Application.Run.
Но выражение Application.Run находится в Program.cs, который, похоже, сгенерирован кодом, поэтому любые изменения могут быть неожиданно потеряны. Кроме того, я не мог найти способ установить текущий поток в STA в свойствах проекта или основной формы, но, возможно, я ищу не в том месте.
Каким образом можно вызвать saveFileDialog.ShowDialog()
в фоновом потоке?
ShowDialog() не следует вызывать из фонового потока - используйте Invoke (..).
Invoke((Action)(() => { saveFileDialog.ShowDialog() }));
Решение очень просто;
Просто добавьте это поверх метода Main [STAThread]
Итак, ваш основной метод должен выглядеть так:
[STAThread]
static void Main(string[] args)
{
....
}
Это работает для меня.
это должно работать, если вы создаете поток, в котором вы вызываете showDialog:
var thread = new Thread(new ParameterizedThreadStart(param => { saveFileDialog.ShowDialog(); }));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Добавьте следующий код на FormLoad
private void Form1_Load(object sender, EventArgs e)
{
Thread myth;
myth = new Thread(new System.Threading.ThreadStart(CallSaveDialog));
myth.ApartmentState = ApartmentState.STA;
myth.Start();
}
Здесь CallSaveDialog
- это поток, и здесь вы можете называть ShowDialog
следующим образом
void CallSaveDialog(){saveFileDialog.ShowDialog();}
В вашем MainForm:
if (this.InvokeRequired) {
this.Invoke(saveFileDialog.ShowDialog());
} else {
saveFileDialog.ShowDialog();
}
Или, если у вас будут другие методы, которые необходимо запустить из потока пользовательского интерфейса:
private void DoOnUIThread(MethodInvoker d) {
if (this.InvokeRequired) { this.Invoke(d); } else { d(); }
}
Затем вызовите свой метод как таковой:
DoOnUIThread(delegate() {
saveFileDialog.ShowDialog();
});