Co to jest AsyncCallback?

79

Jaki jest pożytek z AsyncCallback i dlaczego powinniśmy go używać?

RV.
źródło

Odpowiedzi:

143

Gdy asyncmetoda zakończy przetwarzanie, AsyncCallbackmetoda jest wywoływana automatycznie, co umożliwia wykonanie instrukcji przetwarzania końcowego . Dzięki tej technice nie ma potrzeby odpytywania ani czekania na zakończenie asyncwątku.

Oto więcej wyjaśnień na temat Asynckorzystania z funkcji Callback:

Model wywołania zwrotnego: Model wywołania zwrotnego wymaga określenia metody wywołania zwrotnego i uwzględnienia dowolnego stanu, którego potrzebujemy w metodzie wywołania zwrotnego, aby zakończyć wywołanie. Model wywołania zwrotnego można zobaczyć w poniższym przykładzie:

static byte[] buffer = new byte[100];

static void TestCallbackAPM()
{
    string filename = System.IO.Path.Combine (System.Environment.CurrentDirectory, "mfc71.pdb");

    FileStream strm = new FileStream(filename,
        FileMode.Open, FileAccess.Read, FileShare.Read, 1024,
        FileOptions.Asynchronous);

    // Make the asynchronous call
    IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length,
        new AsyncCallback(CompleteRead), strm);
}

W tym modelu tworzymy nowego AsyncCallbackdelegata, określając metodę do wywołania (w innym wątku) po zakończeniu operacji. Dodatkowo określamy obiekt, którego możemy potrzebować jako stan wywołania. W tym przykładzie wysyłamy obiekt stream, ponieważ będziemy musieli wywołać EndReadi zamknąć strumień.

Metoda, którą tworzymy do wywołania na końcu wywołania, wyglądałaby mniej więcej tak:

static void CompleteRead(IAsyncResult result)
{
    Console.WriteLine("Read Completed");

    FileStream strm = (FileStream) result.AsyncState;

    // Finished, so we can call EndRead and it will return without blocking
    int numBytes = strm.EndRead(result);

    // Don't forget to close the stream
    strm.Close();

    Console.WriteLine("Read {0} Bytes", numBytes);
    Console.WriteLine(BitConverter.ToString(buffer));
}

Inne techniki to Wait-until-done i Polling .

Model oczekiwania do zakończenia Model oczekiwania do zakończenia umożliwia rozpoczęcie wywołania asynchronicznego i wykonanie innej pracy. Po wykonaniu innych czynności możesz spróbować zakończyć połączenie i będzie ono blokowane do momentu zakończenia wywołania asynchronicznego.

// Make the asynchronous call
strm.Read(buffer, 0, buffer.Length);
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);

// Do some work here while you wait

// Calling EndRead will block until the Async work is complete
int numBytes = strm.EndRead(result);

Lub możesz użyć uchwytów oczekiwania.

result.AsyncWaitHandle.WaitOne();

Model odpytywania Metoda odpytywania jest podobna, z wyjątkiem tego, że kod będzie odpytywał, IAsyncResultaby sprawdzić, czy zostało zakończone.

// Make the asynchronous call
IAsyncResult result = strm.BeginRead(buffer, 0, buffer.Length, null, null);

// Poll testing to see if complete
while (!result.IsCompleted)
{
    // Do more work here if the call isn't complete
    Thread.Sleep(100);
}
Użytkownik SO
źródło
1
Czy istnieje sposób, aby to zrobić, aby CompleteRead była funkcją niestatyczną?
greggorob64
1
Tak, możesz utworzyć zarówno metody instancji TestCallbackAPM, jak i CompleteRead.
Użytkownik SO
32

Pomyśl o tym w ten sposób. Masz kilka operacji, które chcesz wykonywać równolegle. Można to włączyć za pomocą wątków, które są wykonywane asynchronicznie. To jest mechanizm „odpal i zapomnij”.

Ale niektóre sytuacje wymagają mechanizmu, w którym można odpalić i zapomnieć, ale potrzebne jest powiadomienie po zakończeniu operacji. W tym celu należy użyć wywołania zwrotnego asynchronicznego.

Operacja jest asynchroniczna, ale oddzwania po jej zakończeniu. Zaletą tego jest to, że nie musisz czekać na operację, aż się zakończy. Możesz wykonywać inne operacje, dzięki czemu Twój wątek nie jest blokowany.

Przykładem może być transfer w tle dużego pliku. Podczas przesyłania danych tak naprawdę nie chcesz blokować użytkownikowi wykonywania innych operacji. Po zakończeniu przesyłania proces oddzwoni do Ciebie przy użyciu metody asynchronicznej, w której prawdopodobnie pojawi się okno komunikatu z komunikatem „Transfer zakończony”.

bobbyalex
źródło