首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >任务中的无限循环- cpu使用率

任务中的无限循环- cpu使用率
EN

Stack Overflow用户
提问于 2015-02-19 21:06:20
回答 4查看 1.5K关注 0票数 0

我正在为watch做一些控制器数据的服务,如果它改变了,我就把它写到DB中。看起来很简单。以前我在Delphi上也意识到了这一点,但现在我使用的是C# (.Net 4.5)。现在服务可以很好地处理100个任务,但是消耗了大约7-8%的CPU时间。我的Delphi服务消耗了大约0%。如何减少服务占用CPU的时间?附注:每个任务都有自己的类实例,用于连接和插入数据库,以及处理数据的本地副本。

代码语言:javascript
复制
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);                   
        }
EN

回答 4

Stack Overflow用户

发布于 2015-02-21 16:36:16

最近,我遇到了一个类似的难题,通过使用一组专门的长时间运行的任务在我的应用程序中执行异步工作,我设法解决了CPU使用率不稳定的问题,如下所示:

代码语言:javascript
复制
    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
    Loop

This image显示了在相同工作负载下的CPU使用率的差异(上午9点以后显示)。

因此,我认为在某些情况下,通过使用像上面这样的专用/长时间运行的任务来绕过线程池可以提高CPU利用率。当然我的也是这样的:-)

票数 0
EN

Stack Overflow用户

发布于 2015-03-03 15:59:30

我转到了timer instructions,因为它是一项windows服务。计时器负载上的每个事件大约为7-10%,之间为0%。我试着应用任务,ThreadSchedule --它们看起来更重。

代码语言:javascript
复制
 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);
        }
    }
票数 0
EN

Stack Overflow用户

发布于 2015-03-03 21:37:48

我转到了内部有无限循环的基本线程。它有无数的线程来满足我的需求。没有繁重的重新创建/重新启动等操作。现在,它像Delphi服务一样工作得很好,但与数据和数据库的工作更舒适。我用这个过程从lambda new thread()=>启动线程:

代码语言:javascript
复制
        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);
                }
            }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28607225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档