Ik heb een applicatie gemaakt welke gebruik maakt van asynchrone sockets. Tenminste, dat dacht ik.
In de documentatie vind ik dat de thread waarop de callback van BeginAccept uitgevoerd wordt een thread uit de (IOCP) threadpool is. Af en toe gebeurt dit ook, maar soms (als er veel binnenkomende verbindingen zijn) wordt de callback uitgevoerd op dezelfde thread als waarop ik BeginAccept aanroep.
Dit lijkt me geen asynchroon gedrag, er wordt immers geen tweede thread gebruikt voor de afhandeling van de callback.
Ik zou hier graag een verklaring voor hebben. Is dit een feature of een bug? Ik kan er verder niks van vinden.
Onderstaand is een stukje code om te testen:
Een gedeelte van de output van async.log ziet er zo uit:
In de documentatie vind ik dat de thread waarop de callback van BeginAccept uitgevoerd wordt een thread uit de (IOCP) threadpool is. Af en toe gebeurt dit ook, maar soms (als er veel binnenkomende verbindingen zijn) wordt de callback uitgevoerd op dezelfde thread als waarop ik BeginAccept aanroep.
Dit lijkt me geen asynchroon gedrag, er wordt immers geen tweede thread gebruikt voor de afhandeling van de callback.
Ik zou hier graag een verklaring voor hebben. Is dit een feature of een bug? Ik kan er verder niks van vinden.
Onderstaand is een stukje code om te testen:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
| using System.Net.Sockets; using System.Net; using System.Threading; using System; using System.IO; namespace TestAsyncSockets { public class AsyncTest { private ManualResetEvent connectionAccepted = new ManualResetEvent(false); TextWriter logger = new StreamWriter("async.log"); public AsyncTest() { } public void Start() { Thread listenthread = new Thread(new ThreadStart(StartListening)); listenthread.Start(); Thread sendthread1 = new Thread(new ThreadStart(StartSending)); sendthread1.Start(); Thread sendthread2 = new Thread(new ThreadStart(StartSending)); sendthread2.Start(); } private void StartListening() { IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 5456); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(localEndPoint); socket.Listen(20); while (true) { connectionAccepted.Reset(); logger.WriteLine("Listening thread id: " + Thread.CurrentThread.ManagedThreadId.ToString() + ", ThreadPoolThread: " + Thread.CurrentThread.IsThreadPoolThread.ToString()); logger.Flush(); socket.BeginAccept(new AsyncCallback(this.AcceptCallback), null); connectionAccepted.WaitOne(); } } /* Deze methode wordt some op listenthread uitgevoerd, soms op een thread uit de threadpool */ private void AcceptCallback(IAsyncResult ar) { int threadPoolThreads; int completionPortThreads; ThreadPool.GetAvailableThreads(out threadPoolThreads, out completionPortThreads); int maxThreadPoolThreads; int maxCompletionPortThreads; ThreadPool.GetMaxThreads(out maxThreadPoolThreads, out maxCompletionPortThreads); logger.WriteLine(String.Format("Receiver thread id: {0}, Nr of threads in Threadpool: {1}, {2}, Max threads in ThreadPool: {3}, {4}, ThreadPoolThread: {5}", Thread.CurrentThread.ManagedThreadId, threadPoolThreads, completionPortThreads, maxThreadPoolThreads, maxCompletionPortThreads, Thread.CurrentThread.IsThreadPoolThread)); logger.Flush(); connectionAccepted.Set(); } private void StartSending() { for (int i = 0; i < 10; i++) { try { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(IPAddress.Loopback, 5456); socket.Disconnect(false); //Thread.Sleep(5); } catch { } } } } } |
Een gedeelte van de output van async.log ziet er zo uit:
code:
1
2
3
4
| Listening thread id: 12, ThreadPoolThread: False Receiver thread id: 12, Nr of threads in Threadpool: 25, 1000, Max threads in ThreadPool: 25, 1000, ThreadPoolThread: False Listening thread id: 12, ThreadPoolThread: False Receiver thread id: 16, Nr of threads in Threadpool: 25, 999, Max threads in ThreadPool: 25, 1000, ThreadPoolThread: True |
De beste ideeën komen als je bezig bent.