我正在为watch做一些控制器数据的服务,如果它改变了,我就把它写到DB中。看起来很简单。以前我在Delphi上也意识到了这一点,但现在我使用的是C# (.Net 4.5)。现在服务可以很好地处理100个任务,但是消耗了大约7-8%的CPU时间。我的Delphi服务消耗了大约0%。如何减少服务占用CPU的时间?附注:每个任务都有自己的类实例,用于连接和插入数据库,以及处理数据的本地副本。
int TagCnt = DataCtrl.TagList.Count;
stopExec = false;
if (TagCnt != 0)
{
tasks = new Task[TagCnt];
for (int i = 0; i <= TagCnt - 1; i++)
{
int TempID = i;
tasks[TempID] = Task.Run(async () => // make threads for parallel read-write tasks // async
{
Random rand = new Random();
TimeSpan delay = TimeSpan.FromMilliseconds(rand.Next(1000, 1500))
try
{
while (!stopExec)
{
cToken.ThrowIfCancellationRequested();
//do basic job here
await Task.Delay(delay, cToken);
}//while end
}
catch (...)
{
...
}
}, cToken);
}发布于 2015-02-21 16:36:16
最近,我遇到了一个类似的难题,通过使用一组专门的长时间运行的任务在我的应用程序中执行异步工作,我设法解决了CPU使用率不稳定的问题,如下所示:
Dim NumThreads As Integer = 10
Dim CanTokSrc As New CancellationTokenSource
Dim LongRunningTasks As Task() = New Task(NumThreads) {}
Dim i As Integer
Do Until i = LongRunningTasks.Count
LongRunningTasks(i) = Task.Factory.StartNew(Sub()
Do Until CanTokSrc.IsCancellationRequested
'DO WORK HERE
Loop
End Sub, CanTokSrc.Token, TaskCreationOptions.LongRunning)
i = i + 1
LoopThis image显示了在相同工作负载下的CPU使用率的差异(上午9点以后显示)。
因此,我认为在某些情况下,通过使用像上面这样的专用/长时间运行的任务来绕过线程池可以提高CPU利用率。当然我的也是这样的:-)
发布于 2015-03-03 15:59:30
我转到了timer instructions,因为它是一项windows服务。计时器负载上的每个事件大约为7-10%,之间为0%。我试着应用任务,ThreadSchedule --它们看起来更重。
private void OnReadTimer(object source, ElapsedEventArgs e) //check states on timer
{
int TagCnt = DataCtrl.TagList.Count;
po.MaxDegreeOfParallelism = DataCtrl.TagList.Count;
// string ss = "tags=" + TagCnt;
//int TempID;
Random rand = new Random();
try
{
if (TagCnt != 0)
{
ParallelLoopResult loopResult = Parallel.For(0, TagCnt - 1, po, (i, loopState) =>
{
po.CancellationToken.ThrowIfCancellationRequested();
int TempID = i;
Thread.Sleep(rand.Next(100, 200));
int ID = 0;
bool State = false;
long WT = 0;
int ParID = 0;
bool Save = false;
ReadStates(TempID, out ID, out State, out WT, out ParID, out Save);
lock (locker)
{
if (Save) WriteState(ID, State, WT, ParID);
}
});
}
}
catch (TaskCanceledException)
{
}
catch (System.NullReferenceException eNullRef)
{
AddLog("Error:" + eNullRef);
}
catch (System.ArgumentOutOfRangeException e0)
{
AddLog("Error:" + e0);
}
catch (Exception e1)
{
//AddLog("Error while processing data: " + e1);
}
}发布于 2015-03-03 21:37:48
我转到了内部有无限循环的基本线程。它有无数的线程来满足我的需求。没有繁重的重新创建/重新启动等操作。现在,它像Delphi服务一样工作得很好,但与数据和数据库的工作更舒适。我用这个过程从lambda new thread()=>启动线程:
void RWDeviceState(int i)
{
try
{
int TempID = i;
long StartTime;
long NextTime;
long Period = 3000;
int ID = 0;
bool State = false;
long WT = 0;
int ParID = 0;
bool Save = false;
while (ExecutionAllowed)
{
Save = false;
ReadStates(TempID, out ID, out State, out WT, out ParID, out Save);
lock (locker)
{
if (Save) WriteState(ID, State, WT, ParID);
}
StartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
NextTime = StartTime + Period;
while (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond < NextTime && ExecutionAllowed)
{
Thread.Sleep(40);
}
}https://stackoverflow.com/questions/28607225
复制相似问题