'How to queue a completion port action (I/O bound function) to CLR ThreadPool

I have an external library that does long running I/O. I wish to create a multithreaded application that will use ThreadPool to limit simultaneous number of threads and I wish to add threads handing these external calls as completion port thread (I/O threads) rather than worker threads (so that limit for compute bound threads) is intact.

I have a code sample, that omits external library but shows what I've tried already.

Does anyone know how to do that? Or is it even possible. Thank you

using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ThreadPoolTest
{
    class MainApp
    {
        static void Main()
        {
            ThreadPool.SetMaxThreads(10, 10);
            ThreadPool.QueueUserWorkItem(DoWork); //doesn't work - a compute-bound thread 

            ThreadPool.SetMaxThreads(10, 10);

             //doesn't work - still a compute-bound thread 
            ((Action<object>)DoWork).BeginInvoke(null, Callback, null);

            Console.Read();
        }

        static void DoWork(object o)
        {
            ShowAvailableThreads();
            //call to external library - that does a long I/O operation
            Thread.Sleep(10);
        }

        static void Callback(IAsyncResult ar)
        {
            ShowAvailableThreads();
        }

        static void ShowAvailableThreads()
        {
            int workerThreads, completionPortThreads;

            ThreadPool.GetAvailableThreads(out workerThreads,
               out completionPortThreads);
            Console.WriteLine("WorkerThreads: {0}," +
               " CompletionPortThreads: {1}",
               workerThreads, completionPortThreads);
        }
    }
}


Solution 1:[1]

You can queue work for the I/O threads as described here.

The managed QueueUserWorkItem queues work to the "worker threads" only. UnsafeQueueNativeOverlapped queues to the I/O threads, as do completions for asynchronous I/O performed on kernel objects that have been bound to the ThreadPool via BindHandle.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Glorfindel