Csharp/CSharp Tutorial/Thread/Asynchronous

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Async Callback Delegate

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;
  public delegate int BinaryOp(int x, int y);
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Main() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId); 
      BinaryOp b = new BinaryOp(Add);
      IAsyncResult iftAR = b.BeginInvoke(10, 10,new AsyncCallback(AddComplete),"adding these numbers.");
      Console.ReadLine();
    }
    static void AddComplete(IAsyncResult itfAR)
    {
      Console.WriteLine("AddComplete() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId); 
      AsyncResult ar = (AsyncResult)itfAR;
      BinaryOp b = (BinaryOp)ar.AsyncDelegate;
      Console.WriteLine("10 + 10 is {0}.", b.EndInvoke(itfAR));
      string msg = (string)itfAR.AsyncState;
      Console.WriteLine(msg);
    }
    static int Add(int x, int y){
      Console.WriteLine("Add() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId); 
      Thread.Sleep(5000);
      return x + y;
    }
  }

Async Delegate

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
  public delegate int BinaryOp(int x, int y);
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Main() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId); 
      BinaryOp b = new BinaryOp(Add);
      IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null);
      while (!iftAR.AsyncWaitHandle.WaitOne(1000, true))
      {
        Console.WriteLine("Doing more work in Main()!");
      }
      int answer = b.EndInvoke(iftAR);
      Console.WriteLine("10 + 10 is {0}.", answer);
      Console.ReadLine();
    }
    static int Add(int x, int y)
    {
      Console.WriteLine("Add() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId); 
      Thread.Sleep(5000);
      return x + y;
    }  
  }

Asynchronous Calls: IAsyncResult

using System;
delegate void FuncToCall(string s);
class MainClass
{
    
    
    public static void WriteLineCallback(IAsyncResult iar)
    {
        Console.WriteLine("In WriteLineCallback");
        FuncToCall func = (FuncToCall) iar.AsyncState;
        func.EndInvoke(iar);
    }
    
    public static void CallWriteLineWithCallback(string s)
    {
        FuncToCall func = new FuncToCall(Console.WriteLine);
        func.BeginInvoke(s, new AsyncCallback(WriteLineCallback), func);
    }
    public static void Main()
    {
        CallWriteLineWithCallback("Hello There");
        
        System.Threading.Thread.Sleep(1000);
    }
}
Hello There
In WriteLineCallback

Asynchronous Calls with Return Values

using System;
using System.Threading;
class MainClass{
    public delegate double MathFunctionToCall(double arg);
    
    public static void MathCallback(IAsyncResult iar)
    {
        MathFunctionToCall mc = (MathFunctionToCall) iar.AsyncState;
        double result = mc.EndInvoke(iar);
        Console.WriteLine("Function value = {0}", result);
    }
    public static void CallMathCallback(MathFunctionToCall mathFunc,double start,double end,double increment)
    {
        AsyncCallback cb = new AsyncCallback(MathCallback);
        
        Console.WriteLine("BeginInvoke: {0}", start);
        mathFunc.BeginInvoke(start, cb, mathFunc);
        start += increment;
    }
    public static void Main()
    {
        CallMathCallback(new MathFunctionToCall(Math.Sin), 0.0, 1.0, 0.2);
        Thread.Sleep(2000);
    }
}
BeginInvoke: 0
Function value = 0

Asynchronous Invocation Of Delegates

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
    public delegate int MyDelegate();
    public class ClassWithDelegate
    {
        public MyDelegate theDelegate;
        public void Run()
        {
            for (; ; )
            {
                if (theDelegate != null)
                {
                    foreach (MyDelegate del in theDelegate.GetInvocationList())
                    {
                        del.BeginInvoke(new AsyncCallback(ResultsReturned), del);
                    } 
                } 
            } 
        } 
        private void ResultsReturned(IAsyncResult iar)
        {
            MyDelegate del = (MyDelegate)iar.AsyncState;
            int result = del.EndInvoke(iar);
            Console.WriteLine("Delegate returned result: {0}", result);
        }
    }
    public class MyHandler
    {
        private int myCounter = 0;
        public void Register(ClassWithDelegate theClassWithDelegate)
        {
            theClassWithDelegate.theDelegate += new MyDelegate(DisplayCounter);
        }
        public int DisplayCounter()
        {
            Thread.Sleep(10000);
            Console.WriteLine("Done with work in DisplayCounter...");
            return ++myCounter;
        }
    }
    public class Test
    {
        public static void Main()
        {
            ClassWithDelegate theClassWithDelegate = new ClassWithDelegate();
            MyHandler fs = new MyHandler();
            fs.Register(theClassWithDelegate);
            theClassWithDelegate.Run();
        }
    }

Asynchronous Results Pattern Example

using System;
using System.Threading;
delegate void WorkerThreadHandler();
public class MainClass
{
  public static AutoResetEvent ResetEvent = new AutoResetEvent(false);
  public static void Main()
  {
      WorkerThreadHandler workerMethod = null;
      IAsyncResult asyncResult = null;
      try
      {
          workerMethod = new WorkerThreadHandler(DoWork);
          asyncResult = workerMethod.BeginInvoke(null, null);
          while(!asyncResult.AsyncWaitHandle.WaitOne(1000, false))
          {
              Console.Write(".");
          }
      }
      finally
      {
          if (workerMethod != null && asyncResult != null)
          {
             workerMethod.EndInvoke(asyncResult);
          }
      }
  }
  public static void DoWork()
  {
      Thread.Sleep(1000);
  }
}

Async Method

using System;
using System.Runtime.Remoting.Messaging;
class MainClass
{
  delegate int MyDelegate(string s, ref int a, ref int b);
  static void Main(string[] args)
  {
    MyDelegate X = new MyDelegate(DoSomething);
    int a = 0;
    int b = 0;
    IAsyncResult ar = X.BeginInvoke("Hello", ref a, ref b, null, null);
    ar.AsyncWaitHandle.WaitOne(10000, false);
    if (ar.IsCompleted)
    {
      int c = 0;
      int d = 0;
      //get results
      X.EndInvoke(ref c, ref d, ar);
      Console.WriteLine(c);
      Console.WriteLine(d);
    }
  }
  //My Async Method
  static int DoSomething(string s, ref int a, ref int b)
  {
    a = 10;
    b = 100;
    Console.WriteLine("Fired! DoSomething1");
    return 0;
  }
}
Fired! DoSomething1
10
100

Call asynchronously

using System;
using System.Threading;
public delegate string WashCar(Car carToDetail);
public class Car{}
class MainClass
{
  public static string DetailCar(Car c)
  {
    Console.WriteLine("Detailing car on thread {0}", Thread.CurrentThread.GetHashCode());
    Thread.Sleep(10000);
    return "Your car is ready!";
  }
  static void Main(string[] args)
  {
    Console.WriteLine("Main() is on thread {0}", Thread.CurrentThread.GetHashCode());
    WashCar d = new WashCar(DetailCar);
    Car myCar = new Car();
    IAsyncResult itfAR = d.BeginInvoke(myCar, null, null);
          
    Console.WriteLine("Done invoking delegate");
    
    string msg = d.EndInvoke(itfAR);
    Console.WriteLine(msg);
  }
}

Pass delegate to deal with the IAsyncResult

using System;
using System.Threading;
public class MainClass
{
    private delegate Decimal Compute( int year );
    private static Decimal DecimalCompute( int year ) {
        Console.WriteLine( "Computing ");
        Thread.Sleep( 6000 );
        return 6.8M;
    }
    private static void DealWithResult( IAsyncResult ar ) {
        Compute work = (Compute) ar.AsyncState;
        Decimal result = work.EndInvoke( ar );
        Console.WriteLine( "Result: {0}", result );
    }
    static void Main() {
        Compute work = new Compute( DecimalCompute );
        work.BeginInvoke( 2004, new AsyncCallback(DealWithResult),work );
        Console.WriteLine( "Waiting for operation to complete." );
        Thread.Sleep( 8000 );
    }
}

Use AsyncCallback

using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
class MainClass
{
  delegate int MyDelegate(string s);
  static void Main(string[] args)
  {
    MyDelegate X = new MyDelegate(DoSomething);
    AsyncCallback cb = new AsyncCallback(DoSomething2);
    IAsyncResult ar = X.BeginInvoke("Hello", cb, null);
    Console.WriteLine("Press any key to continue");
    Console.ReadLine();
  }
  static int DoSomething(string s)
  {
    Console.WriteLine("doooooooooooooooo");
    return 0;
  }
  static void DoSomething2(IAsyncResult ar)
  {
    MyDelegate X = (MyDelegate)((AsyncResult)ar).AsyncDelegate;
    X.EndInvoke(ar);
  }
}
Press any key to continue
doooooooooooooooo

Use async job to compute

using System;
using System.Threading;
public class MainClass
{
    // Declare the delegate for the async call.
    private delegate Decimal Compute( int year );
    // The method that computes the taxes.
    private static Decimal DecimalCompute( int year ) {
        Console.WriteLine( "Computing taxes in thread {0}", Thread.CurrentThread.GetHashCode() );
        Thread.Sleep( 6000 );
        return 4.9M;
    }
    static void Main() {
        Compute work = new Compute(DecimalCompute );
        IAsyncResult pendingOp = work.BeginInvoke( 2004, null, null );

        Thread.Sleep( 3000 );
        Console.WriteLine( "Waiting for operation to complete." );
        Decimal result = work.EndInvoke( pendingOp );
        Console.WriteLine( "Taxes owed: {0}", result );
    }
}
Computing taxes in thread 3
Waiting for operation to complete.
Taxes owed: 4.9