private unsafe void QueueCompletionNotification(IIOCompletionTarget target, FileAsyncIOResult result) { var notificationArgs = new IOCompletionNotificationArgs { Result = result, Target = target, }; ThreadPool.QueueUserWorkItem( state => { var stateArgs = (IOCompletionNotificationArgs)state; stateArgs.Target.OnCompletion(stateArgs.Result); }, notificationArgs); }
private unsafe void ReleaseOvelappedAndQueueCompletionNotification(TaggedOverlapped *overlapped, FileAsyncIOResult result) { // We can now find the external-code callback that needs notification for this request. // We can't allow it to block this thread, which is dedicated to servicing the completion port. // Were it to block, we could starve I/O completion; blocking on other I/O completions could be a deadlock. // So, we guarantee that IIOCompletionTargets run on thread-pool threads - they suffer no special restrictions. IIOCompletionTarget target = ReleaseOverlappedAndGetTarget(overlapped); var notificationArgs = new IOCompletionNotificationArgs { Result = result, Target = target, }; ThreadPool.QueueUserWorkItem( state => { var stateArgs = (IOCompletionNotificationArgs)state; stateArgs.Target.OnCompletion(stateArgs.Result); }, notificationArgs); }