我在管理.Net 4.0 C#上的线程时遇到了问题,我对线程的了解还不足以解决它,所以我在这里发布,希望有人可以给我一些建议。
方案如下:
我们在C#framework 4.0上有一个Windows服务,(1)通过套接字连接到服务器以获取.PCM文件,(2)然后将其转换为.WAV文件,(3)通过电子邮件发送 - SMTP最后(4)通知初始服务器它已成功发送。
安装服务的服务器有8个处理器和8 GB或RAM。
为了允许多处理,我用4个线程构建了服务,每个线程执行我之前提到的每个任务。
在代码上,我有每个任务的类和方法,所以我创建线程并调用方法如下:
Thread eachThread = new Thread(object.PerformTask);
在每个方法中,我有一个While,它检查套接字的连接是否处于活动状态,并根据其状态继续获取数据或处理数据。
while (_socket.Connected){
//perform task
}
问题在于,随着更多服务的安装(同一个Windows服务被复制并指向服务器上的两个端点以通过套接字获取文件),CPU消耗急剧增加,每个服务继续运行并处理文件但是那里是一个时刻,CPU消耗太高,服务器只是崩溃。
问题是:您建议我处理这种情况,我的意思是一般来说,处理这种高度需求的处理任务以避免服务器CPU消耗崩溃的好方法是什么?
感谢。
PS:如果有人需要有关该方案的更多详细信息,请告知我们。
修改1
CPU崩溃我的意思是服务器太慢,我们不得不重新启动它。
修改2
在这里,我发布了部分代码,以便您了解它的编程方式:
while(true){
//starting the service
try
{
IPEndPoint endPoint = conn.SettingConnection();
string id = _objProp.Parametros.IdApp;
using (socket = conn.Connect(endPoint))
{
while (!socket.Connected)
{
_log.SetLog("INFO", "Conectando socket...");
socket = conn.Connect(endPoint);
//if the connection failed, wait 5 seconds for a new try.
if (!socket.Connected)
{
Thread.Sleep(5000);
}
}
proInThread = new Thread(proIn.ThreadRun);
conInThread = new Thread(conIn.ThreadRun);
conOutThread = new Thread(conOut.ThreadRun);
proInThread.Start();
conInThread.Start();
conOutThread.Start();
proInThread.Join();
conInThread.Join();
conOutThread.Join();
}
}
}
编辑3
主题1
while(_socket.Connected) { 尝试 { var conn = new AppConection(ref _objPropiedades);
try { string message = conn.ReceiveMessage(_socket); lock (((ICollection)_queue).SyncRoot) { _queue.Enqueue(message); _syncEvents.NewItemEvent.Set(); _syncEvents.NewResetEvent.Set(); } lock (((ICollection)_total_rec).SyncRoot) { _total_rec.Add("1"); } } catch (SocketException ex) { //log exception } catch (IndexOutOfRangeException ex) { //log exception } catch (Exception ex) { //log exception } //message received } catch (Exception ex) { //logging error } } //release ANY instance that could be using memory _socket.Dispose(); log = null;
线程2
while(_socket.Connected) { 尝试{ _syncEvents.NewItemEventOut.WaitOne();
if (_socket.Connected) { lock (((ICollection)_queue).SyncRoot) { total_queue = _queue.Count(); } int i = 0; while (i < total_queue) { //EMail Emails; string mail = ""; lock (((ICollection)_queue).SyncRoot) { mail = _queue.Dequeue(); i = i + 1; } try { conn.SendMessage(_socket, mail); _syncEvents.NewResetEvent.Set(); } catch (SocketException ex) { //log exception } } } else { //log exception _syncEvents.NewAbortEvent.Set(); Thread.CurrentThread.Abort(); } } catch (InvalidOperationException e) { //log exception } catch (Exception e) { //log exception } } //release ANY instance that could be using memory _socket.Dispose(); conn = null; log = null;
主题3
while(_socket.Connected) {
int total_queue = 0; try { _syncEvents.NewItemEvent.WaitOne(); lock (((ICollection) _queue).SyncRoot) { total_queue = _queue.Count(); } int i = 0; while (i < total_queue) { if (mgthreads.GetThreatdAct() <
mgthreads.GetMaxThread()) { string message =“”; lock(((ICollection)_queue).SyncRoot) {
message = _queue.Dequeue(); i = i + 1; } count++; lock (((ICollection) _queueO).SyncRoot) { app.SetParameters(_socket, _id,
message,_queueO,_syncEvents, _total_Env,_total_err); }
Thread producerThread = new
线程(app.ThreadJob){Name = “ProducerThread_”+ DateTime.Now.ToString( “ddMMyyyyhhmmss”), Priority = ThreadPriority.AboveNormal }; producerThread.Start();
producerThread.Join(); mgthreads.IncThreatdAct(producerThread); } mgthreads.DecThreatdAct(); } mgthreads.DecThreatdAct(); } catch (InvalidOperationException e) { } catch (Exception e) { } Thread.Sleep(500); } //release ANY instance that could be using memory _socket.Dispose(); app = null; log = null; mgthreads = null;
主题4
MessageVO mesVo = fac.ParseMessageXml(_message);
答案 0 :(得分:0)
我会降低线程优先级并让所有线程都通过一个限制并发性到Environment.ProcessorCount的信号量。这不是一个完美的解决方案,但在这种情况下听起来就足够了,并且很容易解决。
编辑:考虑到这一点,您必须将10个服务折叠成一个单独的进程,否则您将无法集中控制正在运行的线程。如果你有10个独立的过程,他们就无法协调。
答案 1 :(得分:0)
由于CPU使用率高,通常不应该崩溃。虽然任何线程都在等待远程事件发生(例如,远程服务器响应请求),但该线程不使用cpu资源。但实际上它正在做某事,它会相应地使用cpu。在您提到的任务中,没有固有的高CPU使用率(因为保存PCM文件,因为WAV不需要复杂的算法),因此高CPU使用率似乎是编程错误的标志。