myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » Dispatcher: Synchrone Callbacks made easy
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Dispatcher: Synchrone Callbacks made easy

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
AyrA AyrA ist männlich
myCSharp.de-Mitglied

avatar-3186.png


Dabei seit: 23.09.2010
Beiträge: 60
Entwicklungsumgebung: Visual Studio 2008 Pro
Herkunft: Schweiz


AyrA ist offline

Dispatcher: Synchrone Callbacks made easy

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Das Problem bei Threads ist, dass nicht einfach auf das Form zugegriffen werden kann. Normalerweise möchte man aber nach dem Ende eines Threads die verarbeiteten Informationen anzeigen. Der Dispatcher vereinfacht dies erheblich. Das System funktioniert über callbacks, ähnlich wie bei javascript üblich. Die callbacks können daher inline definiert werden und haben zugriff auf den Zustand der Methode in der sie definiert werden.

Aufruf (mit inline funktionen):

C#-Code:
Dispatcher.Dispatch(
delegate(object[] args){System.Threading.Thread.Sleep(10000);args[0]="test";},
delegate(object[] args){labelTest.Text=(string)args[0];},
new object[]{null});

Was macht das
Die erste delegate wird asynchron in einem Thread aufgerufen. Die 10 Sekunden Wartedauer beeinflussen nicht die Anwendung.
Die zweite delegate wird aufgerufen, wenn die erste vorbei ist. Die Argumente sind für beide delegates das selbe Array, der erste Aufruf kann also Parameter in den zweiten Aufruf übergeben.
der zweite Aufruf ist immer synchron zum GUI Thread, sofern mindestens ein Form existiert.
Sollte keins existieren (or SYNCHRONIZE direktive ist nicht gesetzt) dann wird die delegate ebenfalls asynchron aufgerufen, dies macht Sinn für Konsolenanwendungen.

Der object-Parameter dient dazu, Argumente zu übergeben. Der Index muss definiert werden (wenn auch null). Verändern der array werte wird jeweils auf der Referenz ausfegührt, deshalb benötigen Stream.Read Aufrufe auch kein "ref" Schlüsselwort. Das selbe Prinzip wird hier ausgenutzt. Der parameter wird an beide callbacks übergeben.

Der obige Aufruf geht davon aus, dass der Aufruf in einem Form mit einem "labelTest" ausgeführt wird

Abhängigkeiten
Läuft unter .NET 2.0. Ist SYNCHRONIZE definiert, dann wird eine Referenz auf System.Windows.Forms benötigt.

Verwendungszwecke
- Hintergrundaufgaben einfach planen und ausführen.
- Events zeitverzögert von Form B nach Form A senden, z.B. wenn Form A eine liste mit einträgen enthält und Form B eine Bestätigung zum verarbeiten aller Einträge einholt, kann A benachrichtigt werden, wenn die Operation abgeschlossen ist.
- Asynchrones I/O. z.B. bei Socket.BeginConnect.
- Wrapper für beliebige klassen die keine synchronen callbacks anbieten oder nicht asynchron arbeiten. (Thread, Socket, TcpListener, Console.In,Out,Err).

C#-Code:
//Define SYNCHRONIZE if it is a window application.
//Console applications do not need this.
#define SYNCHRONIZE

using System.Threading;

#if SYNCHRONIZE
using System.Windows.Forms;
#endif

namespace Dispatch
{
    /// <summary>
    /// callbacks for Dispatch functions
    /// </summary>
    /// <param name="args">Arguments for callback</param>
    public delegate void DispatchHandler(object[] args);

    /// <summary>
    /// Provides an easy event dispatcher
    /// </summary>
    public static class Dispatcher
    {
        /// <summary>
        /// Runs "Method" asynchronously and calls "Callback" synchronously after it
        /// </summary>
        /// <param name="Method">Method to run async</param>
        /// <param name="Callback">Callback to run sync (if possible, otherwise async)</param>
        /// <param name="Args">Arguments for "Method" and "Callback"</param>
        /// <returns>Thread object for the call (already running)</returns>
        public static Thread Dispatch(DispatchHandler Method, DispatchHandler Callback, params object[] Args)
        {
            //Inline functions in C# are almost as easy as in JS.
            Thread T = new Thread(delegate()
            {
                bool called = false;
                Method(Args);
#if SYNCHRONIZE
                //try to call the method in sync with the application loop.
                for (int i = 0; i < Application.OpenForms.Count && !called; i++)
                {
                    if (!Application.OpenForms[i].IsDisposed)
                    {
                        called = true;
                        Application.OpenForms[i].Invoke(Callback, Args);
                    }
                }
#endif
                //if not called, the call it async.
                if (!called)
                {
                    Callback.Invoke(Args);
                }
            });
            //uncomment the next line if you want this call to terminate,
            //if your application exits
            //T.IsBackground = true;
            T.Start();
            return T;
        }
    }
}

Mögliche Anpassungen
- Ermöglichen, dass der DispatchHandler einen Rückgabewert haben kann.
- Ändern des generischen "params object[]" in ein geeigneteres Format.

Schlagwörter: dispatcher, synchron, thread, threads, callback
09.02.2015 15:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
Kingside Kingside ist männlich
myCSharp.de-Mitglied

Dabei seit: 31.05.2014
Beiträge: 60


Kingside ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Sowas habe ich gesucht und wollte hier schon fast einen neuen Thread aufmachen. Vielen Vielen Dank!!!
20.03.2015 21:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Jahre.
Der letzte Beitrag ist älter als 4 Jahre.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 18.09.2019 01:45