30 Stimmen

C# WinForms: Wie setzt man die Hauptfunktion STAThreadAttribute

Ich erhalte die folgende Ausnahme beim Aufruf saveFileDialog.ShowDialog() in einem Hintergrund-Thread:

Aktueller Thread muss auf Single eingestellt sein Thread-Apartment-Modus (STA) versetzt werden, bevor OLE Aufrufe gemacht werden können. Stellen Sie sicher, dass Ihr Hauptfunktion das Attribut STAThreadAttribute markiert ist.

Nach Angaben von :

Um das Problem zu beheben, muss ich Anweisung ein:

Threading.Thread.CurrentThread.ApartmentState = Threading.ApartmentState.STA;

i Anweisung Application.Run.

Aber die Anweisung Application.Run befindet sich in Program.cs, das anscheinend generierter Code ist, so dass alle Änderungen unerwartet verloren gehen könnten. Außerdem konnte ich in den Eigenschaften des Projekts oder des Hauptformulars keine Möglichkeit finden, den aktuellen Thread auf STA zu setzen, aber vielleicht suche ich ja an der falschen Stelle. Was ist der richtige Weg zum Aufruf von saveFileDialog.ShowDialog() in einem Hintergrund-Thread?

58voto

MILAD Punkte 629

Lösung sehr einfach; Fügen Sie der Main-Methode einfach Folgendes hinzu [STAThread]

Ihre Hauptmethode sollte also wie folgt aussehen

 [STAThread]
 static void Main(string[] args)
 {
     ....
 }

Das funktioniert bei mir.

32voto

Nathan Punkte 5864

ShowDialog() sollte nicht von einem Hintergrund-Thread aufgerufen werden - verwenden Sie Invoke(..).

Invoke((Action)(() => { saveFileDialog.ShowDialog() }));

14voto

Mg. Punkte 1419

Dies sollte funktionieren, wenn Sie den Thread erstellen, in dem Sie den showDialog aufrufen:

var thread = new Thread(new ParameterizedThreadStart(param => { saveFileDialog.ShowDialog(); }));
 thread.SetApartmentState(ApartmentState.STA);
thread.Start();

7voto

santosh Kundkar Punkte 149

Fügen Sie folgenden Code in 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();
}

Aquí CallSaveDialog ist ein Thread und hier können Sie ShowDialog wie diese

void CallSaveDialog(){saveFileDialog.ShowDialog();}

1voto

C-Pound Guru Punkte 15319

Auf Ihrem MainForm:

if (this.InvokeRequired) { 
 this.Invoke(saveFileDialog.ShowDialog()); 
} else { 
 saveFileDialog.ShowDialog(); 
}

Oder, wenn Sie andere Methoden haben, die vom UI-Thread aus ausgeführt werden müssen:

  private void DoOnUIThread(MethodInvoker d) {
     if (this.InvokeRequired) { this.Invoke(d); } else { d(); }
  }

Rufen Sie dann Ihre Methode als solche auf:

 DoOnUIThread(delegate() {
    saveFileDialog.ShowDialog();
 });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X