问题描述
我正在为10个tcp客户端使用自定义客户端连接。   ;
I am using custom client connection for 10 tcp clients.
bool _flagScanner1Connect = true;
private xyzTranmissionProtocol xyz1TranmissionProtocol = null;
private static readonly object LockWhileConnectingForScanner1 = new object();
internal ICustomClient Scanner1Conn;
System.Threading.Timer _tmrCheck1ClientConn;
public void Start1ScannerConn() { try { _tmrCheck1ClientConn = new System.Threading.Timer(Check1ScannerConn, null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(5));
}
catch (Exception )
{
}
}
private void Check1ScannerConn(object state)
{if(!_flagScanner1Connect)return;
{ if (!_flagScanner1Connect) return;
lock(LockWhileConnectingForScanner1){
lock (LockWhileConnectingForScanner1) {
if(Scanner1Conn == null || Scanner1Conn.CommunicationState == ClientCommunicationStates.Disconnected){
if (Scanner1Conn == null || Scanner1Conn.CommunicationState == ClientCommunicationStates.Disconnected) {
尝试{_tmrCheck1ClientConn.Change(Timeout.Infinite,Timeout.Infinite);
Scanner1Conn = CustomClientFactory.CreateClient(new CustomClientTcpEndPoint("Scanner IpAdress","Scanner Port Number"));
Scanner1Conn.Connected + = Scanner1Conn_Connected; ;
Scanner1Conn.Disconnected + = Scanner1Conn_Disconnected;
Scanner1Conn.MessageReceived + = Scanner1Conn_MessageReceived;
xyz1TranmissionProtocol = new xyzTranmissionProtocol();
Scanner1Conn.TransmissionProtocol = xyz1TranmissionProtocol;
Scanner1Conn.Connect();
//发送PING消息
_tmrCheck1ClientConn.Change(TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(5));
}
catch(例外)
{
if(_flagScanner1Connect)
尝试
{
Scanner1Conn?.Disconnect();
}
catch {}
try
{
Scanner1Conn?.Dispose();
}
catch {}
try
{
Scanner1Conn = null;
}
catch {}
}
finally
{
_tmrCheckClientConn.Change(TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(5));
}
}
}
}
try { _tmrCheck1ClientConn.Change(Timeout.Infinite, Timeout.Infinite); Scanner1Conn = CustomClientFactory.CreateClient(new CustomClientTcpEndPoint("Scanner IpAdress", "Scanner Port Number")); Scanner1Conn.Connected += Scanner1Conn_Connected; ; Scanner1Conn.Disconnected += Scanner1Conn_Disconnected; Scanner1Conn.MessageReceived += Scanner1Conn_MessageReceived; xyz1TranmissionProtocol = new xyzTranmissionProtocol(); Scanner1Conn.TransmissionProtocol = xyz1TranmissionProtocol; Scanner1Conn.Connect(); //SEND A PING MESSAGE _tmrCheck1ClientConn.Change(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5)); } catch (Exception ) { if (_flagScanner1Connect) try { Scanner1Conn?.Disconnect(); } catch { } try { Scanner1Conn?.Dispose(); } catch { } try { Scanner1Conn = null; } catch { } } finally { _tmrCheckClientConn.Change(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5)); } } } }
我写了10
不同 函数 10
条形码 扫描仪。以上代码适用于1台扫描仪。 如果我使用3个扫描仪 或少于3我的申请将有效。但如果我使用超过3个扫描仪,则发送消息
已收到   ;活动不起作用 应用程序将变得非常缓慢。任何人都可以帮我解决这个问题。
I have written 10different functions for 10bar code scanners. above code is for 1 scanner. if i use 3 scanners or less than 3 my application will work. but if i use more than 3 scanners then messagereceived events will not work And the application will become very slow. can anyone help me out to solve this issue.
推荐答案
你正在调整计时器的间隔很多 - 为什么?您正在使用Threading.Timer,因此它是可重入的。当您运行此代码时,它可能会再次回调,因此您的代码不是计时器安全的。你的Check1ScannerConn方法似乎是
,它是在计时器到期时运行的方法,因此当你将间隔改为5秒时,你正处理这个事件。根据执行代码所需的时间,您可能已经再次调用此方法。顶部的锁
阻止您输入代码,但它仍然阻止了计时器线程。基本上,代码运行的时间越长,就越有可能吃掉线程池线程,同时阻塞等待上一个请求完成。这根本不是
。你添加的扫描程序越多,它就会越快,直到你的线程池线程用完为止。
You are mucking with your timer's interval a lot - why? You're using a Threading.Timer so it is reentrant. It is possible that while you're running this code that it calls back again, hence your code isn't timer safe. Your Check1ScannerConn method seems to be the method that is run when the timer expires so you're in the middle of handling this event when you change the interval to 5 seconds. Depending upon how long that code takes to execute you may have already called back into this method again. The lock at the top prevents you from entering the code but it is still blocking the timer thread. Basically the longer your code runs the more likely you are to eat up the thread pool threads while blocked waiting for the previous request to complete. This is not going to scale at all. The more scanners you add the faster it is going to be until you run out of thread pool threads to run against.
将计时器更改为5秒后不久,你将其设置为5秒所以这个最终的代码似乎是多余的。根本不要弄乱计时器间隔。使用一个简单的变量来管理重入,可能需要仔细检查以处理竞争条件。
Shortly after changing the timer to 5 seconds you then set it to 5 seconds again so this final code seems redundant. Don't muck with the timer interval at all. Use a simple variable to manage reentrancy with perhaps a double check to handle race conditions.
您应该决定的一件事是扫描仪的生命周期。在您的代码中,您将扫描仪视为短暂的。但是你正在向他们提起事件。由于您从未取消过这些事件,因此扫描仪将比您想象的更长时间
。短期对象通常不需要事件处理程序。如果扫描仪是共享实体,那么创建和销毁它们可能在这里有意义,但事件可能不会。如果扫描仪的创建成本很高,那么预先创建它们并在应用程序的生命周期中重复使用它们可能会更好。只有你可以决定采用哪种方法。我将假设无关紧要的是你有一个创建此创建的CreateScanner方法并返回扫描仪以供
使用。要复制现有代码,我会这样做。
//Since we don't have a consistent scanner object we'll have to create a sync object ourselves
private Mutex _lckScanner1 = new Mutex(false);
private void Check1ScannerConn ( object state )
{
//Check for reentrancy and abort
if (!_lckScanner1.WaitOne(1))
return;
try
{
using (var scanner = CreateScanner())
{
//Does this do the actual ping??
scanner.Open();
};
} finally
{
_lckScanner1.ReleaseMutex();
};
}
如果您决定先预先创建扫描仪,那么很多"扫描仪1"会在前面创建扫描仪。具体的东西可以概括下来。除了可重入检查之外,你的计时器唯一能做的就是ping通话。
If you instead decide to create the scanners up front then a lot of this "scanner 1" specific stuff can be generalized down. The only thing your timer would do, beside the reentrant check, is the ping call.
这篇关于c#线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!