短い紹介: 私は、さまざまな時間間隔で機能している他のアプリケーションとサービスを監視するWindowsサービスを用意しています。 このサービスは、監視対象アプリケーション(「monitor」という名前)ごとに1つのタイマー(System.Threading.Timer)を使用します。 異なるタイプのアプリケーションでは、さまざまなタイプのモニターが必要です。一部は同期して動作し、他のタイプは非同期(たとえば、HttpClientを使用するもの)です。System.Threading.Timer内での非同期操作の異常な動作
私はタイマーで非同期呼び出しが必要なところまで行きました。 私はここにそれを掲示できるように制限にコードを単純化しました。これはコンソールプロジェクトに直接実行できます。 私の問題は、より多くのタイマが導入されているので、このコードは非常に奇妙な動作をしているということです。 モニターの実行時間は、非同期操作(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を使用します。それに応じて設定します。 答えをありがとう。 –