[英]Efficient multiple tcp clients with intervals
我一直在用C#編寫一個命令行程序,該程序使用都連接到同一服務器的多個tcp客戶端。 每個客戶端都駐留在其自己的線程中。 目前,我正在嘗試一種有效的方法,例如在4個線程之間有效地傳播5個請求。
目前,我的代碼如下所示,但最終還是導致請求相互重疊。 有誰知道如何有效地防止這些重疊?
// Max connections is 4, interval is 200
// Loop once to give tcp clients chance to connect
var tcpClients = new TcpClient[_maxConnections];
for(int i = 0; i < _maxConnections; i++)
{
tcpClients[i] = new TcpClient();
tcpClients[i].Connect(host, port);
}
// Loop again to setup tasks
for(int i = 0; i < _maxConnections; i++)
{
Task.Factory.StartNew(TcpHandler, tcpClients[i]);
// Sleep so every task starts separate from each other.
Thread.Sleep(_interval);
}
然后,TcpHandler代碼如下所示:
public static void TcpHandler(Object o)
{
// active is already declared
while(_active)
{
var tcpClient = (TcpClient) o;
// .. do some send and receive...
Console.WriteLine("Something here..");
Thread.Sleep(_interval * _maxConnections);
}
}
因此,您可以看到,我正在努力為每個正在執行的線程之間提供足夠的空間,然后它們仍然重疊。
如何使該線程並行運行而沒有任何重疊,並限制所有4個線程每秒傳播5次?
還是我要解決所有這些錯誤?
假設每個客戶端都需要一個單獨的線程,並且在給定時間(不重疊),只有一個線程可以與服務器通信,則TcpHandler
方法中的lock
就足夠了:
// Max connections is 4, interval is 200
// Loop once to give tcp clients chance to connect
var tcpClients = new TcpClient[_maxConnections];
// dedicated lock object
static readonly object lockObject = new object();
然后在您的TcpHandler方法中
public static void TcpHandler(Object o)
{
// active is already declared
while(_active)
{
//DO NON-SOCKET RELATED STUFF HERE
// ... code ...
//
//DO SOCKET RELATED STUFF HERE
lock(lockObject)
{
var tcpClient = (TcpClient) o;
// .. do some send and receive...
Console.WriteLine("Something here..");
Thread.Sleep(_interval * _maxConnections);
}
}
}
我不太確定為什么要這樣做,但是我在Windows服務中使用了System.Timers(實際上是一組定時器),並且錯開了開始時間(間隔)。
在Elapse事件中,您可以使用lock(myobject){},以使它們不重疊?
吉娜
我認為您正在使用睡眠來管理連接時間。為什么不改而設置“最大連接延遲”,然后使用BeginConnect
和Timer
來照顧連接。
例如。
//setup a timer variable
TCPClient connectionOpening;
_connecting = true;
_connected = false;
connectionOpening = tcpClient;
timer.change(5000, Infinite)
tcpClient.BeginConnect(ClientConnectCallback, tcpClient)
void ClientConnectCallback(iasyncresult ar)
{
_timer.change(infinite, infinite);
TCPClient tcp = (TCPClient)ar.AsyncState;
try
{
//if we have timed out because our time will abort the connect
tcp.EndConnect(ar);
_connected = true;
_connecting = false;
//we are now connected... do the rest you want to do.
//get the stream and BeginRead etc.
}
catch (Exception ex) // use the proper exceptions IOException , socketException etc
{
if (!_connecting)
{
//We terminated the connection because our timer ticked.
}
else
{
//some other problem that we weren't expecting
}
}
void TimerTick(object state)
{
_connecting = false;
_connected = false;
connectionOpening.Close();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.