在我的应用程序中,我有少量线程(5)执行以下方法:
private void ThreadMethod()
{
while(true)
{
if(CurrentItem != null)
{
HandleCurrentItem();
}
Thread.Sleep(200);
}
}
从我所看到的情况来看,这不是推荐的做法,但大多数论据都是因为你没有反应能力,你无法取消线程,或者时机不准确。这些对我来说都不是问题,但是我担心在此浪费太多的CPU资源。根据我在01:05:35看到的here,当您调用Sleep方法时,处理器将获得充分利用。
我的问题:
在我的方案中,这是一个不错的解决方案吗? 如果没有,怎么做得更好?
注意:我正在使用.Net Framework 4.0
注意2:这些线程位于类的不同实例中,因此CurrentItem
是每个线程的不同对象。
答案 0 :(得分:3)
当您想要在最后一次操作后200毫秒执行某些操作时,您也可以使用Timer
而不是睡眠。这不会旋转锁定处理器。
var timer = new Timer(200);
timer.Elapsed += (sender, args) =>
{
if(CurrentItem != null)
HandleCurrentItem();
};
timer.AutoReset = true;
timer.Start();
.NET Framework类库包含四个名为Timer的类,每个类都提供不同的功能:
System.Timers.Timer
,它会触发事件并定期在一个或多个事件接收器中执行代码。该类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。System.Threading.Timer
,它定期在线程池线程上执行单个回调方法。回调方法是在实例化定时器时定义的,无法更改。与System.Timers.Timer类一样,此类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。System.Windows.Forms.Timer
,一个Windows窗体组件,用于触发事件并定期在一个或多个事件接收器中执行代码。该组件没有用户界面,专为在单线程环境中使用而设计;它在UI线程上执行。System.Web.UI.Timer
,一个ASP.NET组件,定期执行异步或同步网页回发。答案 1 :(得分:2)
您可以制作方法async
并将其设为await
:
private async void ThreadMethod()
{
while(true)
{
if(CurrentItem != null)
{
HandleCurrentItem();
}
await Task.Delay(200);
}
}
这不会阻止线程
注意异步等待关键字只能使用.Net 4.0
在visual studio 2012+上与Microsoft.Bcl.Async
一起使用(您可以在nuget上获取此包)。
您也可以使用此代码段(信用到:Calvin Fisher):
new System.Threading.ManualResetEvent(false).WaitOne(1000);
答案 2 :(得分:1)
您可以使用Hangfire实现干净的实施。这将使您可以更好地控制您的任务,如果功能执行或失败,您也将获得反馈。
您可以创建这样的预定作业:
RecurringJob.AddOrUpdate(() => Console.WriteLine("Recurring!"),Cron.Daily);
您可以在文档中探索更多选项。
答案 3 :(得分:-1)
您可以使用AutoRestEvent
private void ThreadMethod()
{
AutoResetEvent _restEvent = new AutoResetEvent(false);
_restEvent.Reset();
while(true)
{
if(CurrentItem != null)
{
HandleCurrentItem();
}
_restEvent.WaitOne(200); // Set a timeout in ms.
}
}