2012-09-27 55 views
1

我試圖偵聽來自各種傳入端口(〜20)的UDP數據包。我想專用3-5個線程來接收和處理這些數據包。這對於Windows中的IO完成端口來說似乎是理想的情況。我不明白的是如何執行多個到更少映射的多個套接字來檢查一組較小的線程。使用來自C#中有限線程池上多個套接字的IO完成端口

以下代碼創建所有套接字並開始異步接收操作。

for(int ix = 0; ix < 20; ix++) 
{ 
    var socket = new Socket(AddressFamily.InterNetwork, 
          SocketType.Dgram, ProtocolType.Udp); 
    socket.Bind(new IPEndPoint(IPAddress.Any, ix+6000)); 
    var e = new SocketAsyncEventArgs(); 
    e.Completed+=OnReceive; 
    e.SetBuffer(buffer, ix*1024*1024, 1024*1024); 
    socket.ReceiveFromAsync(e); 
    _sockets.Add(socket); 
} 

我明白,當接收到數據包的每個的onReceive信息將被稱爲...

static void OnReceive(object sender, SocketAsyncEventArgs e) 
{ 
    Console.WriteLine("Received {0} bytes", e.BytesTransfered); 
    if(!((Socket)sender).ReceiveFromAsync(e)) 
     e_Completed(sender, e); 
} 
  1. 如何限制運行的onReceive事件的線程數?
  2. 在極少數情況下OnReceive方法遞歸調用自己的次數很少的情況下,防止堆棧溢出的最佳方法是什麼?
+0

尋找等效於CreateIoCompletionPort的NumberOfConcurrentThreads參數。 – Superman

回答

0

不知道我明白你的意思與線程接收和處理。接收發生在後臺。

無論如何,我會使用BlockingCollection。

的onReceive可能看起來像這樣

private static BlockingCollection<byte[]> _received = new ... 

static void OnReceive(object sender, SocketAsyncEventArgs e) { 
    byte[] data = new byte[e.BytesTransfered]; 
    Array.Copy(e.buffer, e.Offset, data, 0, e.BytesTransfered); 
    _received.Add(data) 
    ... 
} 

然後你只需要使用TPL/PLINQ來處理線程的請求數量接收到的數據。

var parallelOptions = new ParalellOptions { MaxDegreeOfParallelism = 3 }; 
Parallel.ForEach(_received.GetConsumingPartitioner(), 
       parallelOptions, 
       data => { 
        // do processing 
        ... 
       }); 
+0

同意接收發生在後臺,但完成端口已經調用線程調度器,只是想知道如何控制。不想將內存拷貝拷貝到另一個線程並限制在那裏,因爲我會失去完成端口的好處。 – Superman

相關問題