【发布时间】:2018-04-22 05:27:05
【问题描述】:
简介: 我有一个 Windows 服务,它监视其他应用程序和服务,如果它们在不同的时间间隔运行。 该服务为每个受监视的应用程序(称为“监视器”)使用一个计时器(System.Threading.Timer)。 不同类型的应用程序需要不同类型的监视器,有些同步工作,有些异步工作(例如,使用 HttpClient 的那些)。
所以我到了需要在计时器中进行异步调用的地步。 我已将代码简化到极限,以便可以将其发布在这里。它可以直接运行到控制台项目中。 我的问题是这段代码有一个非常奇怪的行为,因为引入了更多的计时器 - 它运行得越难,直到它根本没有响应(超过 20 个计时器)。 监控运行时间不正是异步操作中设置的延迟(100ms)吗?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace TestMain
{
class TestMain
{
private static List<TestTimer> timers = new List<TestTimer>();
static void Main(string[] args)
{
for (int i = 0; i < 20; i++)
{
TestMain.timers.Add(new TestTimer(i));
}
Console.WriteLine("Press [Enter] to exit.");
Console.ReadLine();
}
public class TestTimer
{
public Int32 Id { get; private set; }
private Timer timer;
public TestTimer(Int32 id)
{
this.Id = id;
this.timer = new Timer(this.Test, null, 1000, 30 * 1000);
}
private void Test(Object state)
{
TestWorker t = new TestWorker(this.Id);
t.Run();
}
}
public class TestWorker
{
public Int32 Id { get; private set; }
private Stopwatch sw = new Stopwatch();
public TestWorker(Int32 id) { this.Id = id; }
public void Run()
{
this.RunAsync().Wait();
}
private async Task RunAsync()
{
this.Log(String.Format("Start[{0,2}]", this.Id));
this.sw.Restart();
await Task.Run(() => { System.Threading.Thread.Sleep(100); }).ConfigureAwait(false);
this.sw.Stop();
this.Log(String.Format(" End[{0,2}] Duration=[{1}]", this.Id, (Int32)this.sw.ElapsedMilliseconds));
}
private void Log(String text)
{
Console.WriteLine(String.Format("{0,20} {1}", DateTime.Now, text));
}
}
}
}
我附加了一个带有运行的打印屏幕。 Console Printscreen
【问题讨论】:
-
异步操作完成后不再等待部分问题但线程间仍存在瓶颈的解决方案。对我来说正确的解决方案是使用 ThreadPool.SetMinThreads 的解决方案,因为它可以随时间扩展,因为在服务启动时,所有需要监控的应用程序(数量和类型)都是已知的,并且可以设置最小线程数因此。谢谢你的回答。
标签: c# asynchronous timer