2009-11-23 3 views
3

На самом деле у меня есть трудное время в понимании пары BeginInvoke() и EndInvoke().C# Асинхронная операция

class AsynchronousDemo 
{ 

    public delegate void DemoDelegate(); 
    static void Main() 
    { 

     DemoDelegate d = PrintA; 

     IAsyncResult AResult = d.BeginInvoke(Callback,null); 
     d.EndInvoke(AResult); 
     Console.ReadKey(true); 
    } 

    static void PrintA() 
    { 
     Console.WriteLine("....Method in Print A Running ...."); 
     Thread.Sleep(4000); 
     Console.WriteLine("....Method in Print A Completed..."); 
    } 


    static void Callback(IAsyncResult ar) 
    { 
     Console.WriteLine("I will be finished after method A 
     completes its execution"); 
    } 
} 

1) Используем ли мы "EndInvoke()", чтобы указать окончание "асинхронную операцию" из BeginInvoke() ..?

2) Каково реальное использование этих пар?

3) Могу ли я получить простые и приятные примеры, чтобы лучше понять его?

ответ

10

Представьте, что у вас есть долгое задание, и вы можете делать только одно за раз.Обычно, чтобы сделать это, вам придется перестать делать все остальное.

// pseudocode 
Main() { 
    DoLaundry() 
    GoAboutYourDay() 
} 

DoLaundry() { 
    // boring parts here 
} 

Теперь представьте, что вы хотите, чтобы у вас был день, когда вы делаете стирку. Одним из решений было бы заставить кого-то другого сделать это. Итак, вы отведите его в уборную, скажите им, что делать, дайте им одежду и скажите им позвонить вам, когда они будут сделаны. В свою очередь, они возвращают вам билет, чтобы они снова могли найти вашу одежду, когда захотите.

// pseudocode 
Main() { 
    ticket = DoLaundry.BeginDoing(CallMeWhenDone) 
    GoAboutYourDay() 
    ticket.WaitUntilDone() 
} 

CallMeWhenDone(ticket) { 
    cleanLaundry = DoLaundry.FinishDoing(ticket) 
} 

Как работает асинхронная работа.

BeginInvoke Вы сообщаете программе, что вам нужно сделать (делегат), что вызвать, когда это будет сделано (обратный вызов), и что делать с (состоянием). Вы возвращаете IAsyncResult, который является объектом, который вам нужно вернуть, чтобы получить ваш результат. Затем вы можете делать другие вещи или использовать WaitHandle в IAsyncResult для блокировки до завершения операции.

Обратный вызов: Когда асинхронная операция завершается, он будет вызывать этот метод, предоставляя вам тот же IAsyncResult, как и раньше. На этом этапе вы можете извлечь из него свой объект состояния или передать IAsyncResult в EndInvoke.

EndInvoke: Эта функция принимает IAsyncResult и находит результат операции. Если он еще не закончен, он будет блокироваться до тех пор, пока это не произойдет, поэтому вы обычно вызываете его внутри обратного вызова.

Это шаблон, который часто используется во всей структуре, а не только для делегатов функций. Такие вещи, как соединения с базой данных, сокеты и т. Д., Часто имеют пары «Начало/конец».

MSDN содержит документацию по образцу здесь: http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx

+0

Отлично explanation.would быть очень полезно для начинающих, как я. – user215675

1

BeginInvoke запускает асинхронную операцию EndInvoke ждет до конца этой функции и возвращает результат. это еще один способ выполнить потоки в C#, отличные функции - это то, что begininvoke принимает поток из пула потоков, что неверно для класса Thread, а другое - это то, что вы можете передавать параметры и получать результат для функции потока более простым способом , вот пример http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html

1

Я не знаю, как объяснить это достаточно хорошо, но эта статья должна помочь:
Asynchronous Programming Using Delegates на MSDN

Выдержки:
........... .. Если вызывается метод BeginInvoke, среда выполнения CLR запускает запрос и немедленно возвращается к вызывающему. Целевой метод называется асинхронно в потоке из пула потоков. Исходный поток, который отправил запрос, может продолжить выполнение параллельно с целевым методом. Если в вызове метода BeginInvoke был указан метод обратного вызова, метод обратного вызова вызывается, когда целевой метод заканчивается. В методе обратного вызова метод EndInvoke получает возвращаемое значение и любые параметры ввода/вывода или только выход. Если ни один метод обратного вызова не указываются при вызове BeginInvoke, EndInvoke может быть вызван из потока, который называется BeginInvoke .....

1) Используют ли мы «EndInvoke()», чтобы указать окончание " асинхронная операция "BeginInvoke() ..?
Нет, вы используете, что для получения возвращаемых значений или ... смотри выше

2) Каково реальное использование этих пар?
Таким образом, вы можете сделать асинхронный вызов синхронного метода и т.д.

3) Могу ли я получить некоторые простые и хорошие примеры, чтобы понять это более правильно?
Я уверен, что Google может сделать это лучше, чем у меня: P

1

Я использую Begin Invoke/End Invoke построить для запуска служб окна.

Например:

public ServiceName() 
    { 
     //constructor code goes here 
    } 

    protected override void OnStart(string[] args) 
    { 
     ExecuteDelegate ed = new ExecuteDelegate(Execute); 
     AsyncCallback ac = new AsyncCallback(EndExecution); 
     IAsyncResult ar = ed.BeginInvoke(ac, ed); 
     Log.WriteEntry("Service has started."); 
    } 

    protected void EndExecution(IAsyncResult ar) 
    { 
     ExecuteDelegate ed = (ExecuteDelegate)ar.AsyncState; 
     ed.EndInvoke(ar); 
     Stop(); 
     Log.WriteEntry("Service has stopped."); 
    } 

    protected void Execute() 
    { 
     //Code goes here 
     ... 
    } 

    protected override void OnStop() 
    { 
     Log.WriteEntry("Service has stopped."); 
    } 

По существу: Call BeginInvoke, чтобы начать выполнение метода в новом потоке. Когда поток завершен, метод, вызываемый при соединении потока, должен вызвать EndInvoke.

Смежные вопросы