我在这个类的顶部创建了一个信号量实例
public static SemaphoreSlim _zReportSemaphore = new SemaphoreSlim(1, 500);
在我的代码中,我需要检索并发送一些数据。
while (_isRunning)
{
try
{
xBsonDocument = null;
//I think its very clear in this line...
MongoDBDAO.xGetInstance().GetZReportData(ref xBsonDocument);
foreach (BsonDocument item in xBsonDocument)
{
try
{
ThreadObject xThreadObject = new ThreadObject();
xThreadObject.m_strTerminalId = item.GetValue("_id")["TERMINAL_ID"].ToString();
xThreadObject.m_strZNo = item.GetValue("_id")["Z_NO"].ToString();
m_xBuildAndSendZReportThread =
new Thread(new ParameterizedThreadStart(vBuildAndSendZReport));
m_xBuildAndSendZReportThread.Start(xThreadObject);
}
catch (Exception xException)
{
xException.TraceError();
continue;
}
Thread.Sleep(m_litleStepQTime);
}
}
catch (Exception xException)
{
Thread.Sleep(m_bigStepQTime);
Trace.vInsertError(xException);
continue;
}
Thread.Sleep(m_iSleepTime);
}
此主题目标是将文件发送到ftp
private void vBuildAndSendZReport(object prm_objParameters)
{
_zReportSemaphore.Wait();
RetriveDataFromMongoAndSend();
_zReportSemaphore.Release();
}
在这个结构中;如果我不使用信号量它工作得很好但有时线程计数超载CPU或内存使用量和机器一直在粉碎。
1-如何使用这种纤细的信号量控制数据使用(平衡,隔离线程等)?
2-我可以在生产中使用SemaphoreSlim进行此类工作吗?使用像这样的工作流程组织可能有什么优缺点? 是否可以改善效果?在我的特殊情况下
3-是否有另一种替代方案可以提供系统资源管理,并将结束技术异常管理
答案 0 :(得分:2)
当信号量结束其所有线程时是否有任何事件
没有。它甚至不清楚这可能意味着什么。例如,如果由于线程调度问题,此时您在信号量中只有一个正在运行的线程,并且该线程在一个或多个其他线程尝试之前完成,释放信号量,那么您希望发生什么?获得信号量?
信号量无法检测到这种情况与每个线程不同。
如果您想知道某些异步操作集合何时完成,您需要特别等待。 .NET中有许多选项,包括:
Thread.Join()
。Task
来运行异步任务而不是Thread
,并使用Task.WhenAll()
(或更不用说Task.WaitAll()
)等待它们完成。CountdownEvent
。为您开始的每项任务致电AddCount()
,让每项任务在完成后调用Signal()
,然后等待CountdownEvent
。
顺便说一下,您发布的代码在其他方面是可疑的:
SemaphoreSlim
的最大数量,为什么这个最大值与初始计数不一样?您实际上是否希望比拨打Release()
更频繁地致电Wait()
?Thread.Sleep()
的代码通常不正确。不清楚为什么要这样做,但可能有更好的方法来解决你试图用这些电话解决的任何问题。没有好Minimal, Complete, and Verifiable example,我无法肯定地说那些事情是错的。但他们说得对的可能性很小。 :)
答案 1 :(得分:2)
这是“Semaphore 和 SemaphoreSlim 使用最佳实践”在 Google 上的第一次点击,所以我想添加 1 条评论:
至少,这段代码
semaphore.Wait();
DoSomeThing();
semaphore.Release();
应该是最低的
semaphore.Wait();
try
{
DoSomeThing();
}
finally
{
semaphore.Release();
}
否则,如果 DoSomeThing 中发生异常,您可能最终永远不会再次释放信号量...
在异步编程中,考虑使用
await semaphore.WaitAsync();