简体   繁体   中英

How to reduce high CPU usage at a windows service?

I am looking forward to resolve a specific problem with my windows service. It uses about 25% CPU and I think, that this is way to much to be honest for the tasks it has to do.

The windows service includes 3 threads, which are used as filewatcher. If a specific type of textfile is created they starts a stored procedure on a sql server depending..

3 filewatchers, because there are 3 filetypes, which I have to watch for.

This is the code I am currently using:

watcher.cs:

internal class Watcher
    {
        private List<FileSystemWatcher> _fileWatcher;
        private Regex _regex;
        public bool started;

        public Watcher()
        {
            started = false;
            _fileWatcher = new List<FileSystemWatcher>();
            _regex = new Regex(@"(?<=Anz_)(.*)(.txt*@)(.*)");
            initAllWatcher();
        }


        private void initAllWatcher()
        {
            // LBH:
            var watcher = new FileSystemWatcher();
            watcher.Filter = ConfigurationManager.AppSettings["FilterLBH"];
            watcher.Path = ConfigurationManager.AppSettings["FilePath"];
            watcher.Created += onCreated;
            _fileWatcher.Add(watcher);

            // LSC:
            watcher = new FileSystemWatcher();
            watcher.Filter = ConfigurationManager.AppSettings["FilterLSC"];
            watcher.Path = ConfigurationManager.AppSettings["FilePath"];
            watcher.Created += onCreated;
            _fileWatcher.Add(watcher);

            // LEM:
            watcher = new FileSystemWatcher();
            watcher.Filter = ConfigurationManager.AppSettings["FilterLEM"];
            watcher.Path = ConfigurationManager.AppSettings["FilePath"];
            watcher.Created += onCreated;
            _fileWatcher.Add(watcher);
        }

        public void Run()
        {
            foreach (var filewatcher in _fileWatcher)
            {
                filewatcher.EnableRaisingEvents = true;
            }

            started = true;

            Thread.CurrentThread.IsBackground = true;
            Thread.CurrentThread.Priority = ThreadPriority.Lowest;

            while (started)
            {
            }
        }

        private async void onCreated(object Source, FileSystemEventArgs Arg)
        {
            await execute(Arg);
        }

        private async Task execute(FileSystemEventArgs Arg)
        {
            string tablename = _regex.Split(Arg.Name)[1];
            string targetDatabase = _regex.Split(Arg.Name)[3];

            if (tablename.Equals("") == false)
            {
                if (targetDatabase.Equals("") == false)
                {
                    using (var dbConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
                    {
                        var command = new SqlCommand(ConfigurationManager.AppSettings["StoredProcedure"], dbConnection);
                        command.CommandTimeout = dbConnection.ConnectionTimeout;
                        command.CommandType = CommandType.StoredProcedure;
                        command.Parameters.Add("@strParDbTabelle", SqlDbType.VarChar).Value = tablename;
                        command.Parameters.Add("@strParDbSchema", SqlDbType.VarChar).Value = "dbo";
                        command.Parameters.Add("@strParDbName", SqlDbType.VarChar).Value = targetDatabase;

                        try
                        {
                            await command.ExecuteNonQueryAsync();
                        }
                        catch (System.Exception)
                        {
                            throw;
                        }
                    }
                }
            }
        }
    }

program.cs:

internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
            ServiceBase[] ServicesToRun;

            ServicesToRun = new ServiceBase[]
            {
                new BaanJobActiService()
            };

            ServiceBase.Run(ServicesToRun);
        }
    }

Since I added these lines to my code:

Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Priority = ThreadPriority.Lowest;

the CPU usage melt down to a minimum, if other processes require CPU usage.. which currently helps, but I think, that this can't be the final solution.

So probably one of you guys can teach me, what I could improve and probably why I have to change it, to get a better performance?!

That would be awesome! Thank you in advance. :-)

PS: I know the way I initialize the three watchers isn't the best way, but that shouldn't be the point I think..

PPS: I implemented the execution of the query async, because this are very long running queues and without this implementation I ran into timeout problems..^^

Adding Thread.Sleep(10) into the while-loop did the job for me. Removing the loop wasn't possible, because the filewatcher didn't work without it.

Anyways.. this solution brought the CPU usage down to 0 - 0.5% which is quit nice compared to 25-30%!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM