ずーっと気になっていたんですが、Ubuntu上でサーバーのTCPソケットをAcceptAsyncかけていたら、しばらくアクセスがない状態だと1秒程度の遅延が発生していました。そして、連続したアクセスだとこれは起きなかったんです。
元々のBjdではWhileとSleepによるポーリングを行っていたので、おそらくそんなことは起きなかっただろうと思っています。(そもそも、Begin/Endが動かなかったので、根拠はない!)
同じことが、ManualResetEventSlimeでも起きました。ある程度時間がたったときに、シグナルセット後のWait解放が1秒くらい。これ、Windowsでは起きなかったんですよね。
正直、そこまでプラットフォームに詳しい人間ではないので、なぜこうなるのか?は理解できませんでした。ただ、どうすれば?に関しては、「深い眠りにつかないようにする」っていう発想で回避しました。
- tTcp.Wait(this.Kernel.CancelToken); 94 + while (true) 95 + { 96 + if (tTcp.Wait(2000, this.Kernel.CancelToken)) 97 + break; 98 + if (tTcp.Status == TaskStatus.Canceled) 99 + break; 100 + }
Waitを2秒までとして、完了時はループを抜け、キャンセル時もループを抜けます。こうすることで2秒に一回このWaitが実行されます。そして、結果として遅延1秒はなくなりました。
SpinWaitの絡みとか、タイムスライスのルールとかありそうなんですが、ブラックボックスです。Darkが作るBlackなだけに・・・
これが、Kernelによるものなら、今後もこういう仕様ということになるでしょうし、.Net Coreのものであれば、改善されていくかもしれません。ので、現時点ではこのコードは、一つの回避策として整理してくださいませ!
それでは!