What\'s actually difference between Asynchronous Programming Model and Event-based Asychronous Pattern?
Which approach to use and when
The Asynchronous Programming Model (APM) is the model you see with BeginMethod(...)
and EndMethod(...)
pairs.
For example here is a Socket
using the APM implementation:
var socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// ...
socket.BeginReceive(recvBuffer, 0, recvBuffer.Length,
SocketFlags.None, ReceiveCallback, null);
void ReceiveCallback(IAsyncResult result)
{
var bytesReceived = socket.EndReceive(result);
if (bytesReceived > 0) { // Handle received data here. }
if (socket.Connected)
{
// Keep receiving more data...
socket.BeginReceive(recvBuffer, 0, recvBuffer.Length,
SocketFlags.None, ReceiveCallback, null);
}
}
The Event-based Asynchronous Pattern (EAP) is the model you see with MethodAsync(...)
and CancelAsync(...)
pairs. There's usually a Completed
event. BackgroundWorker
is a good example of this pattern.
As of C# 4.5, both have been replaced by the async/await
pattern, which is using the Task Parallelism Library (TPL). You will see them marked with Async
after the method name and usually returning an awaitable Task
or Task
. If you are able to target .NET 4.5, you should definitely use this pattern over the APM or EAP design.
For example, compressing a (potentially large) file asynchronously:
public static async Task CompressFileAsync(string inputFile, string outputFile)
{
using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read))
using (var outputStream = File.Create(outputFile))
using (var deflateStream = new DeflateStream(outputStream, CompressionMode.Compress))
{
await inputStream.CopyToAsync(deflateStream);
deflateStream.Close();
outputStream.Close();
inputStream.Close();
}
}