I know something about the IOCP, but I'm a little confused with APM.
static FileStream fs;
static void Main(string[] args)
{
fs = new FileStream(@"c:\bigfile.txt", FileMode.Open);
var buffer = new byte[10000000];
IAsyncResult asyncResult = fs.BeginRead(buffer, 0, 10000000, OnCompletedRead, null);
Console.WriteLine("async...");
int bytesRead = fs.EndRead(asyncResult);
Console.WriteLine("async... over");
}
static void OnCompletedRead(IAsyncResult ar)
{
Console.WriteLine("finished");
}
I wonder, is the read action executed by an IO thread asynchronously? Or a worker thread in a thread pool?
And the callback function OnCompletedRead
, is it also executed by an IO thread in CLR thread pool?
Are these two threads the same one? If not, there are two threads generated, one executes the read action and another does the callback.
The not-equal-to operator ( != ) returns true if the operands don't have the same value; otherwise, it returns false .
In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...
C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.
In C/C++, the # sign marks preprocessor directives. If you're not familiar with the preprocessor, it works as part of the compilation process, handling includes, macros, and more.
If you don't use an AsyncCallback argument with BeginRead then there is only one thread that runs code in your program. This uses IO completion ports to signal when the IO is complete by running a small amount of code on a thread in the IO thread pool to update the status of the operation as being complete. When you call EndRead it will block the current thread until the IO operation is complete. It is asynchronous in that when you start the read operation the current thread does not need to do anything other than wait for the IO hardware to perform the read operation, so you can do other things in the meantime and then decide when you want to stop and wait for the IO to finish.
If you do pass in an AsyncCallback then when the IO operation is complete it will execute a small amount of code on an IO thread pool thread which will trigger your callback method to be executed on a thread from the .NET thread pool.
Usually, mclaassen is right about the nature of IO bound work, IOCP and the APM. When BeginRead
executes, it does so asynchronously all the way down to kernel mode. But, there is one caveat specifically in your example that he didn't mention in his answer.
In your example, you use the FileStream
class. One important thing to note is that if you dont use the FileStream
overload that accepts a useAsync
boolean, when you invoke a BeginWrite
/ EndWrite
operation, it will queue work on a new ThreadPool
thread.
This is the proper overload:
public FileStream(
string path,
FileMode mode,
FileAccess access,
FileShare share,
int bufferSize,
bool useAsync
)
From MSDN:
useAsync:
Type: System.Boolean
Specifies whether to use asynchronous I/O or synchronous I/O. However, note that the underlying operating system might not support asynchronous I/O, so when specifying true, the handle might be opened synchronously depending on the platform. When opened asynchronously, the BeginRead and BeginWrite methods perform better on large reads or writes, but they might be much slower for small reads or writes. If the application is designed to take advantage of asynchronous I/O, set the useAsync parameter to true. Using asynchronous I/O correctly can speed up applications by as much as a factor of 10, but using it without redesigning the application for asynchronous I/O can decrease performance by as much as a factor of 10.
You have to make sure each specific method implementing the APM pattern truly uses true asynchronous work all the way down.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With