什么是AsyncCallback?


79

AsyncCallback的用途是什么?为什么要使用它?

Answers:


143

async方法完成处理后,AsyncCallback将自动调用该方法,在该方法中可以执行后处理语句。使用此技术,无需轮询或等待async线程完成。

这是有关Async回调用法的更多说明:

回调模型:回调模型要求我们指定要进行回调的方法,并在回调方法中包括完成呼叫所需的任何状态。在以下示例中可以看到回调模型:

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);
}

在此模型中,我们将创建一个新的AsyncCallback委托,指定一个当操作完成时要调用的方法(在另一个线程上)。另外,我们指定了一些可能需要的对象作为调用状态。在此示例中,我们将发送流对象,因为我们需要调用EndRead并关闭流。

我们创建的在调用结束时要调用的方法如下所示:

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));
}

其他技术是Wait-until-donePolling

Wait-Until-Done模型使用Wait-Until-Done模型可以启动异步调用并执行其他工作。完成其他工作后,您可以尝试结束调用,它将阻塞直到异步调用完成。

// 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);

或者您可以使用等待句柄。

result.AsyncWaitHandle.WaitOne();

轮询模型轮询方法与之类似,不同之处在于代码将对进行轮询IAsyncResult以查看其是否已完成。

// 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);
}

1
有没有一种方法可以使CompleteRead是一个非静态函数?
greggorob64 2010年

1
是的,您可以同时创建TestCallbackAPM和CompleteRead实例方法。
SO用户

32

这样想吧。您有一些要并行执行的操作。您可以通过使用异步执行的线程来启用此功能。这是一种解雇机制。

但是在某些情况下,您需要一种机制,您可以激发并忘记该机制,但是在操作完成时需要通知。为此,您将使用异步回调。

该操作是异步的,但操作完成后会回叫您。这样做的好处是您不必等待操作完成即可。您可以自由执行其他操作,因此不会阻塞您的线程。

一个示例是大型文件的后台传输。在传输过程中,您实际上并不想阻止用户执行其他操作。传输完成后,该过程将使用异步方法将您重新调用,您可能会在其中弹出一个消息框,显示“传输完成”。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.