Calling async methods from a Windows Service

前端 未结 2 764
渐次进展
渐次进展 2020-12-13 04:35

I have a Windows Service written in C# that periodically fires off background jobs. Typically, at any given time, several dozen heavily I/O bound Tasks (downloading large fi

2条回答
  •  有刺的猬
    2020-12-13 05:06

    Not an answer per se, but a year after posting this question we're moving this service to an Azure Cloud Service. I've found the Azure SDK's Worker Role template to be a very good example of properly calling async from sync, providing cancellation support, dealing with exceptions, etc. It's not quite apples-to-apples with Windows Services in that the latter doesn't provide an equivalent to the Run method (you need to kick off your work in OnStart and return immediately), but for what it's worth, here it is:

    public class WorkerRole : RoleEntryPoint
    {
        private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
    
        public override void Run() {
            Trace.TraceInformation("WorkerRole1 is running");
    
            try {
                this.RunAsync(this.cancellationTokenSource.Token).Wait();
            }
            finally {
                this.runCompleteEvent.Set();
            }
        }
    
        public override bool OnStart() {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 12;
    
            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    
            bool result = base.OnStart();
    
            Trace.TraceInformation("WorkerRole1 has been started");
    
            return result;
        }
    
        public override void OnStop() {
            Trace.TraceInformation("WorkerRole1 is stopping");
    
            this.cancellationTokenSource.Cancel();
            this.runCompleteEvent.WaitOne();
    
            base.OnStop();
    
            Trace.TraceInformation("WorkerRole1 has stopped");
        }
    
        private async Task RunAsync(CancellationToken cancellationToken) {
            // TODO: Replace the following with your own logic.
            while (!cancellationToken.IsCancellationRequested) {
                Trace.TraceInformation("Working");
                await Task.Delay(1000);
            }
        }
    }
    

提交回复
热议问题