I still don't get Delegates

2019-03-22 02:45发布

Isn't the use of delegates to help with some asynchronous cases? I tried the following but my UI still hangs. When on earth do you use delegates?

       Public Class Form1
    Private Delegate Sub testDelegate()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
 System.EventArgs) Handles Button1.Click

        Dim d As testDelegate = New testDelegate(AddressOf Add)
        d.Invoke()

    End Sub

    Private Sub Add()
        For i As Integer = 0 To 10000
            TextBox1.Text = i + 1
        Next
    End Sub
End Class

7条回答
孤傲高冷的网名
2楼-- · 2019-03-22 03:40

Here's what I sent to a coworker:

Basically delegates can be used for Callbacks, Events and Asynchronous processing.

Here’s some sample code, copy and paste each example to a new command line project.

//Callbacks    
//-------------------------------------------------------------------------------------------------------     
delegate double DiscountRule(); // Declaration
delegate string MessageFormat(); // Declaration

class Message    
{
    public string Instance() { return "You save {0:C}"; }
    public static string Class() { return "You are buying for {0:C}"; }

    public void Out(MessageFormat format, double d)
    {
        System.Console.WriteLine(format(), d);

    }
}

class Discount
{
    public static double Apply(DiscountRule rule, double amount)
    {
        return rule() * amount; // Callback
    }

    public static double Maximum() { return 0.50; }
    public static double Average() { return 0.20; }
    public static double Minimum() { return 0.10; }
    public static double None() { return 0.00; }
}

class TestDelegate1
{
    public static void Main()    
    {   
        DiscountRule[] rules = { // Instantiations  
             Discount.None,
             Discount.Minimum,    
             Discount.Average,    
             Discount.Maximum,    
             };

        // Instantiation with a static method    
        MessageFormat format = Message.Class;

        double buy = 100.00;    
        Message msg = new Message();             
        msg.Out(format, buy); // Invocation     

        // Instantiation with an instance method    
        format = msg.Instance;

        foreach (DiscountRule r in rules)    
        {    
            double saving = Discount.Apply(r, buy); // Invocation    
            msg.Out(format, saving); // Invocation    
        }    
    }    
}

//--------------------------------------------------------------------------------------------------------    
//Events:     

//the delegate creates a new type    
delegate void UpdateEventHandler();

class Subject    
{    
    private int data;

    public int GetData() { return data; }   
    public void SetData(int value) { data = value; Changed(); }    
    public event UpdateEventHandler Changed;    
}

class Observer    
{    
    public Observer(Subject s) { subject = s; }    
    public Subject GetSubject() { return subject; }   
    private Subject subject;   
}

class HexObserver : Observer
{    
    public HexObserver(Subject s)    
        : base(s)   
    {    
        s.Changed += Update;   
    }

    public void Update()    
    {   
        System.Console.Write("0x{0:X} ", GetSubject().GetData());    
    }    
}

class DecObserver : Observer    
{
     public DecObserver(Subject s)    
        : base(s)    
    {    
        s.Changed += Update;   
    }

    public void Update()    
    {    
        System.Console.Write("{0} ", GetSubject().GetData());    
    }    
}

class TestEvent    
{    
    public static void Main()    
    {   
        Subject s = new Subject();

        //assigns a Hex observer to object s (the constructor does the += assignment)    
        HexObserver ho = new HexObserver(s);

        //assigns a Decimal observer to object s    
        DecObserver co = new DecObserver(s);     

        for (int c; ; )    
        {    
            System.Console.Write("\nEnter a character" +    
            "(followed by a return, ctrl-C to exit): ");

            c = System.Console.Read();    
            s.SetData(c);    
            System.Console.Read(); // Two reads to get rid of the \r\n on PC.    
            System.Console.Read();   
        }    
    }    
}

.

//--------------------------------------------------------------------------------------------------------  
//Asynchronous processing (from http://msdn.microsoft.com/en-us/library/h80ttd5f(VS.71).aspx)         
using System;    
using System.Runtime.Remoting.Messaging;

// Create an asynchronous delegate.    
public delegate bool FactorizingAsyncDelegate (    
         int factorizableNum,     
         ref int primefactor1,    
         ref int primefactor2);

// Create a class that factorizers the number.    
public class PrimeFactorizer    
{    
   public bool Factorize(
                int factorizableNum,      
                ref int primefactor1,    
                ref int primefactor2)   
   {    
      primefactor1 = 1;    
      primefactor2 = factorizableNum;

      // Factorize using a low-tech approach.    
      for (int i=2;i<factorizableNum;i++)   
      {
         if (0 == (factorizableNum % i))    
         {
            primefactor1 = i;    
            primefactor2 = factorizableNum / i;    
            break;    
         }    
      }

      if (1 == primefactor1 )    
         return false;    
      else    
         return true   ;    
   }    
}

// Class that receives a callback when the results are available.    
public class ProcessFactorizedNumber    
{    
   private int _ulNumber;

   public ProcessFactorizedNumber(int number)   
   {    
      _ulNumber = number;   
   }

   // Note that the qualifier is one-way.    
   [OneWayAttribute()]    
   public void FactorizedResults(IAsyncResult ar)    
   {
      int factor1=0, factor2=0; 

      // Extract the delegate from the AsyncResult.      
      FactorizingAsyncDelegate fd = (FactorizingAsyncDelegate)((AsyncResult)ar).AsyncDelegate;

      // Obtain the result.    
      fd.EndInvoke(ref factor1, ref factor2, ar);

      // Output the results.    
      Console.WriteLine("On CallBack: Factors of {0} : {1} {2}",     
                   _ulNumber, factor1, factor2);    
   }    
}

// Class that shows variations of using Asynchronous    
public class Simple    
{    
   // The following demonstrates the Asynchronous Pattern using a callback.    
   public void FactorizeNumber1()    
   {
      // The following is the client code.    
      PrimeFactorizer pf = new PrimeFactorizer();    
      FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

      int factorizableNum = 1000589023, temp=0; 

      // Create an instance of the class that is going   
      // to be called when the call completes.   
      ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

      // Define the AsyncCallback delegate.    
      AsyncCallback cb = new AsyncCallback(fc.FactorizedResults);

      // You can use any object as the state object.    
      Object state = new Object();

      // Asynchronously invoke the Factorize method on pf.   
      IAsyncResult ar = fd.BeginInvoke(
                           factorizableNum,     
                           ref temp, 
                           ref temp,     
                           cb,     
                           state);          
      //    
      // Do some other useful work.    
      //. . .    
   }    

   // The following demonstrates the Asynchronous Pattern using a BeginInvoke, followed by waiting with a time-out.    
   public void FactorizeNumber2()    
   {    
      // The following is the client code.    
      PrimeFactorizer pf = new PrimeFactorizer();    
      FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

      int factorizableNum = 1000589023, temp=0; 

      // Create an instance of the class that is going     
      // to be called when the call completes.
      ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

      // Define the AsyncCallback delegate.    
      AsyncCallback cb =     
           new AsyncCallback(fc.FactorizedResults);

      // You can use any object as the state object.    
      Object state = new Object();

      // Asynchronously invoke the Factorize method on pf.   
      IAsyncResult ar = fd.BeginInvoke(   
                        factorizableNum,     
                        ref temp,     
                        ref temp,     
                        null,    
                        null); 

      ar.AsyncWaitHandle.WaitOne(10000, false);

      if (ar.IsCompleted)  
      {   
         int factor1=0, factor2=0;          

         // Obtain the result.    
         fd.EndInvoke(ref factor1, ref factor2, ar);    

         // Output the results.    
         Console.WriteLine("Sequential : Factors of {0} : {1} {2}", 
                       factorizableNum, factor1, factor2);   
      }    
   }

   public static void Main(String[] args)    
   {    
      Simple simple = new Simple();    
      simple.FactorizeNumber1();    
      simple.FactorizeNumber2();   
   }
查看更多
登录 后发表回答