Start asynchronous WPF-Application via Console

Bild: Microsoft .Net
In folgendem Tutorial beschreibe ich, wie eine Consolenanwendung ein WPF-Fenster öffnen kann. Das ganze funktioniert einmal Synchron und einmal Asynchron über einen zweiten Thread.
Zu aller erst müssen einmal die benötigten Referenzen eingebunden werden. Für die WPF-Anwendung sind das: PresentationFramework, PresentationCore und WindowsBase.


Der Code für das synchrone Fenster sieht wie folgt aus:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace WpfConApp
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Program prg = new Program();
        }

        public Program()
        {
            Application app = new Application();
            app.Startup += new StartupEventHandler(ApplicationStart);
            app.Run();
        }

        public void ApplicationStart(Object sender, StartupEventArgs e)
        {
            Window window = new Window();
            window.Show();
        }
    }
}
Zuerst wird die statische Main-Methode aufgerufen. Diese wird jedoch von einem STAThread aufgerufen. STA steht für Single Thread Apartment. Die genaue Bedeutung kann hier nachgelesen werden. Es ist wichtig zu wissen, dass jede WPF-Application nur in einem STA-Apartment-State lauffähig ist.
Sobald der Konstruktor aufgerufen wird erzeugt er eine Application und übergibt ihr als Startmethode einen Event-Handler. Die Application ist wichtig für das Fenster, da es sonst sofort wieder aufgeräumt werden würde, sobald die Funktion verlassen wird. Es wäre also nur ganz kurz zu sehen. Die Application kümmert sich jedoch um die Fenster. Die Run-Methode bleibt so lange stehen bis alle Fenster beendet wurden. Hier ist auch das Problem: Das eigentlich Programm kann nicht weiterarbeiten, wenn nicht alle Fenster geschlossen wurden. Abhilfe schafft hier ein zusätzlicher Thread.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading;

namespace WpfConApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Program prg = new Program();
            Console.WriteLine("Hey hey");
        }

        public Program()
        {
            Thread myThread = new Thread(this.threadStart);
            myThread.SetApartmentState(ApartmentState.STA);
            myThread.Start();
        }

        public void threadStart()
        {
            Application app = new Application();
            app.Startup += new StartupEventHandler(ApplicationStart);
            app.Run();
        }

        public void ApplicationStart(Object sender, StartupEventArgs e)
        {
            Window window = new Window();
            window.Show();
        }
    }
}
Über die Methode SetApartmentState wird dem neuen Thread auch ein STA-Apartment-State zugeteilt. Während der neue Thread sich um die Fenster kümmert, kann der alte Thread gemütlich weiterlaufen. Das [STAThread] über der Main-Methode ist nicht mehr notwendig.
Anstelle einer Methode kann die Application auch gleich ein Fenster für den Start übergeben werden. Das ganze geschieht über:
app.StartupUri = new Uri("Window.xaml", UriKind.Relative);
Um auf Elemente des STAThreads zugreifen zu können muss der jeweilige Dispatcher angesprochen werden.
window.Dispatcher.Invoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate
            {
                window.Title = str;
                return null;
            }), null);
Bookmark and Share

0 Kommentare:

Kommentar veröffentlichen