Heim > Backend-Entwicklung > C++ > Wie aktualisiere ich eine GUI alle 30 Sekunden sicher aus einem Hintergrundthread?

Wie aktualisiere ich eine GUI alle 30 Sekunden sicher aus einem Hintergrundthread?

Linda Hamilton
Freigeben: 2025-01-10 10:20:42
Original
375 Leute haben es durchsucht

How to Safely Update a GUI from a Background Thread Every 30 Seconds?

Aktualisieren Sie die GUI sicher alle 30 Sekunden über einen Hintergrundthread

In diesem Artikel erfahren Sie, wie Sie Threads sicher in Ihrer Anwendung verwenden, Fehler vermeiden und die Notwendigkeit umsetzen, die GUI alle 30 Sekunden von einem Hintergrundthread aus zu aktualisieren.

Der Benutzer hat zunächst versucht, einen BackgroundWorker zu verwenden und ihn in einer While-Schleife auszuführen, aber es verursachte eine Ausnahme, da der Hintergrund-Worker-Thread kein STA-Thread war.

Der richtige Ansatz besteht darin, Datenbankaufrufe von GUI-Updates zu trennen. Datenbankaufrufe sollten in einem Hintergrundthread (mit BackgroundWorker) durchgeführt werden. Nachdem der Aufruf abgeschlossen ist, wird ein Fortschrittsereignis ausgelöst, um den Hauptthread zu benachrichtigen, die GUI zu aktualisieren.

Vom Benutzer bereitgestellter Code, der diesen Ansatz demonstriert:

<code class="language-C#">public class UpdateController
{
    private UserController _userController;
    private BackgroundWorker _backgroundWorker;

    // ...

    public void Update()
    {
        _backgroundWorker.RunWorkerAsync();
    }

    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // UI 更新
        _userController.UpdateUsersOnMap();
        Update(); // 此处存在潜在问题,递归调用可能导致堆栈溢出
    }

    public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // 大型数据库任务
    }
}</code>
Nach dem Login kopieren

Benutzer stehen jedoch vor einer weiteren Herausforderung: Wie können alle 30 Sekunden Updates ausgelöst werden? Das Hinzufügen eines Ruhezustands von 10 Sekunden im RunWorkerCompleted-Ereignishandler ist nicht möglich, da dadurch die GUI einfriert.

Um dieses Problem zu lösen, kann ein Timer verwendet werden, um die Update-Methode regelmäßig aufzurufen, die wiederum einen Datenbankaufruf und eine anschließende GUI-Aktualisierung initiiert. Eine bessere Lösung besteht darin, den rekursiven Aufruf von RunWorkerCompleted in Update() zu vermeiden und stattdessen System.Timers.Timer oder System.Windows.Forms.Timer zu verwenden, um die Aktualisierungshäufigkeit zu steuern. Dadurch wird sichergestellt, dass die GUI weiterhin reagiert und potenzielle Stapelüberlauffehler vermieden werden.

Die vorgeschlagene verbesserte Codestruktur lautet wie folgt (unter Verwendung von System.Timers.Timer):

<code class="language-C#">public class UpdateController
{
    private UserController _userController;
    private BackgroundWorker _backgroundWorker;
    private System.Timers.Timer _timer;

    public UpdateController()
    {
        _backgroundWorker = new BackgroundWorker();
        _backgroundWorker.DoWork += backgroundWorker_DoWork;
        _backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;

        _timer = new System.Timers.Timer(30000); // 30秒
        _timer.Elapsed += Timer_Elapsed;
        _timer.AutoReset = true;
    }

    public void Start()
    {
        _timer.Start();
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        _backgroundWorker.RunWorkerAsync();
    }

    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // UI 更新,确保在UI线程执行
        _userController.BeginInvoke(new Action(() => _userController.UpdateUsersOnMap()));
    }

    public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // 大型数据库任务
    }
}</code>
Nach dem Login kopieren

Dieser verbesserte Code verwendet Timer, um die Aktualisierungshäufigkeit zu steuern, vermeidet das durch rekursive Aufrufe verursachte Risiko und verwendet BeginInvoke, um sicherzustellen, dass UI-Updates im UI-Thread ausgeführt werden, wodurch die Reaktionsfähigkeit der GUI sichergestellt wird. Denken Sie daran, zum richtigen Zeitpunkt _timer.Stop() anzurufen, um den Timer zu stoppen.

Das obige ist der detaillierte Inhalt vonWie aktualisiere ich eine GUI alle 30 Sekunden sicher aus einem Hintergrundthread?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage