Autor Beitrag
kostonstyle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 94



BeitragVerfasst: Di 16.02.10 11:32 
hallo miteinander
habe wiedermal eine Frage, und zwar geht es um dieser Codeausschnitt
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
AsyncCallback callback = new AsyncCallback(ar =>
         {
            // EndInvoke aufrufen, um das Ergebnis zu erhalten
            long primeNumber = primeNumberDelegate.EndInvoke(ar);

            // Wenn Sie statt eines Lambda-Ausdrucks oder einer 
            // anonymen Methode für den Callback eine normale 
            // Methode verwenden, erhalten Sie eine Referenz auf 
            // den Delegaten folgendermaßen
            // AsyncResult result = (AsyncResult)ar;
            // Func<long, long> primeNumberDelegate =
            //   (Func<long, long>)ar.AsyncDelegate;

            // Das Label aktualisieren und den Schalter wieder aktivieren
            this.Dispatcher.Invoke(DispatcherPriority.Normal,
               new Action(() =>
               {
                  this.lblInfo.Content = primeNumber.ToString();
                  this.btnCalculatePrimeNumber.IsEnabled = true;
               }));
         });

Hier wird ein Instanz von der Delegate AsyncCallback erzeugt.
Die Definition von den Delegate
ausblenden C#-Quelltext
1:
    public delegate void AsyncCallback(IAsyncResult ar);					

Was ich nicht gewusst habe ist, dass man ein Delegate instanzieren kann. Das Argument ar, warum kann man hier ein Lambda Ausdruck zuweisen, obwohl der Typ definiert ist(IAsyncResult). IAsyncResult ist ein Interface, muss man nicht hier die Methode implementieren.
Da ich ein Anfänger bin, kenne ich nur einfache Bespiele für den Einsatz von Delegaten. Aber hier, ist so kompliziert.....

Gruss kostonstyle
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 16.02.10 19:55 
user profile iconkostonstyle hat folgendes geschrieben Zum zitierten Posting springen:
Was ich nicht gewusst habe ist, dass man ein Delegate instanzieren kann.
Kann man bzw. muss man, denn Delegates sind auch "nur" Objekte. Mit dem Instanzieren hast du aber etwas falsch verstanden, dort übergibst du nicht die Argumente des Delegates. Was sollte bei so einem Code auch passieren?
ausblenden C#-Quelltext
1:
2:
IAsyncResult ar = ...;
AsyncCallback ac = new AsyncCallback(ar); // ?


Ein Delegate ist schließlich ein Methodenzeiger, also musst du dem Konstruktor eine Methode übergeben:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
void MyCallback(IAsyncResult ar) { ... }

AsyncCallback ac = new AsyncCallback(MyCallback);
// oder kurz:
// AsyncCallback ac = MyCallback;

Der Code mit Lambda-Ausdruck (oder anonymer Methode) ist dazu exakt äquivalent:
ausblenden C#-Quelltext
1:
AsyncCallback ac = new AsyncCallback(ar => ...);					


In diesem Sinne ist der Code auch etwas merkwürdig (woher stammt der?), man würde normalerweise genauso wie bei MyCallback einfach
ausblenden C#-Quelltext
1:
2:
3:
AsyncCallback ac = ar => {
  ...
};
schreiben. Explizite news auf Delegate-Typen braucht man seit 2.0 eigentlich überhaupt nicht mehr.

_________________
>λ=
kostonstyle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 94



BeitragVerfasst: Mi 17.02.10 11:04 
das Beispiel habe ich aus dem Buch Visual C#. Dieser Codeausschnitt von dir macht die Definition von Delegate Methode deutlicher für ein Anfänger
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
void MyCallback(IAsyncResult ar) { ... }

AsyncCallback ac = new AsyncCallback(MyCallback);
// oder kurz:
// AsyncCallback ac = MyCallback;

in dieser Methode kann man dann den Instanz ar von Type IAsyncResult nutzen. Zum Beispiel
ausblenden C#-Quelltext
1:
2:
3:
4:
void MyCallback(IAsyncResult ar)
   {
     bool complete = ar.IsCompleted;
   }

So weit so klar.
Aber wenn so mit Lambda Ausdruck geschrieben wird
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
 AsyncCallback callback = new AsyncCallback(ar =>
         {
            // EndInvoke aufrufen, um das Ergebnis zu erhalten
            long primeNumber = primeNumberDelegate.EndInvoke(ar);

            // Wenn Sie statt eines Lambda-Ausdrucks oder einer 
            // anonymen Methode für den Callback eine normale 
            // Methode verwenden, erhalten Sie eine Referenz auf 
            // den Delegaten folgendermaßen
            // AsyncResult result = (AsyncResult)ar;
            // Func<long, long> primeNumberDelegate =
            //   (Func<long, long>)ar.AsyncDelegate;

            // Das Label aktualisieren und den Schalter wieder aktivieren
            this.Dispatcher.Invoke(DispatcherPriority.Normal,
               new Action(() =>
               {
                  this.lblInfo.Content = primeNumber.ToString();
                  this.btnCalculatePrimeNumber.IsEnabled = true;
               }));
         });

ist für einen Anfänger so schwierig zu nachvollziehen. Wie kann ich hier das Argument ar in diesem Codeblock nutzen?
Das Beispiel findet ihr im Anhang.

Danke kostonstyle
Einloggen, um Attachments anzusehen!
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 17.02.10 20:32 
user profile iconkostonstyle hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich hier das Argument ar in diesem Codeblock nutzen?
Noch einmal: Wichtig ist, dass Folgendes exakt äquivalent ist.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
void MyCallback(AsyncResult ar)
{
  long primeNumber = primeNumberDelegate.EndInvoke(ar);
  ...
};

primeNumberDelegate.BeginInvoke(startNumber, MyCallback, null);


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
primeNumberDelegate.BeginInvoke(startNumber,
  // (AsyncResult ar) => // Ohne Type Inference
  ar => {
    long primeNumber = primeNumberDelegate.EndInvoke(ar);
    ...
  }, null);



PS: In den meisten Fällen (und spätestens ab 4.0 mit der Task Parallel Library) sind Asynchronous Delegates nicht wirklich hilfreich. Hier würde ich eher so etwas verwenden:
ausblenden C#-Quelltext
1:
2:
3:
4:
ThreadPool.QueueUserWorkItem(state => {
  long primeNumber = NextPrimeNumber(startNumber);
  Dispatcher.BeginInvoke(...);
});

_________________
>λ=
kostonstyle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 94



BeitragVerfasst: Do 18.02.10 08:27 
entschuldige, was ich immer noch nicht verstehe, ist das man das Argument ar ein Lambda Ausdruck zuweisen kann, dass ist so unlogisch, zu mindest für ein Anfänger wie ich.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Do 18.02.10 16:41 
"=>" ist keine Zwuweisung!

ar => { ... } ist der komplette Lambda-Ausdruck, also inklusive des "ar =>". Links vom "=>" stehen die Parameter (also was bei einer "normalen" Methode in der Klammer käme) und rechts vom "=>" steht, was mit den Parametern gemacht wird.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".