我正在嘗試在 Core 5.0 上構建一個作業服務。我的樹基本上是這樣的 =>
1 -) Program.cs 2-) Worker.cs 3-) MyStartUp.cs 4-) Client.cs
在 MyStartUp.cs 我得到一個串列并根據串列呼叫客戶端類一些服務器。
在 Client 類中,我連接到設備并將讀取的資料寫入資料庫。
設備數近1200臺,服務器方式為TCP/IP。
對于撰寫這樣的作業人員服務,您最好的建議是什么?如何以最佳形式使用執行緒?
下面是我的第一次嘗試。這種形式是有效的,但是對于 1000 個不同的客戶端來說太慢了,因為客戶端中有太多的讀取。
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
StartUp startUp = new StartUp();
}
}
public class StartUp
{
public StartUp()
{
//... get client datas and initialize client object
StartClients();
}
public void StartClients()
{
foreach (var item in ClientList)
{
new Thread(item.Run).Start();
}
}
}
public class Client
{
System.Timers.Timer timer ;
public Client()
{
timer = new Timer();
timer.Interval = 100;
timer.Elapsed = Timer_Elapsed;
//... initialize client connection and database
}
public void Run()
{
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
//... write values of read client to database
}
}
uj5u.com熱心網友回復:
假設您有 1k 個每 100 毫秒運行一次的計時器,并假設每個計時器滴答需要 50 毫秒來執行。這意味著每個計時器需要 500 毫秒/秒,或一個內核的 50%,而您需要 500 個內核來跟上作業。您可能沒有那么多內核,也沒有 IO 來處理請求,這意味著作業將開始堆積,您的計算機將或多或少地凍結,因為它沒有時間更新 UI。
50ms 可能是對所用時間的高估,但即使是 5ms,你也可能會遇到問題,除非你在怪物服務器上運行它。
解決方案是將輪詢頻率降低到更合理的頻率,例如每 100 秒而不是每 100 毫秒。或者讓一個或多個執行緒盡可能快地輪詢您的設備。例如:
private BlockingCollection<MyClient> clients = new ();
private List<Task> workers = new ();
public void StartWorker(){
workers.Add(Task.Run(Run));
void Run(){
foreach(var client in clients.GetConsumingEnumerable()){
// Do processing
clients.Add(client); // re-add client to queue
}
}
}
public void CloseAllWorkers(){
clients.CompleteAdding();
Task.WhenAll(workers).Wait();
}
我會注意到的用法Thread主要被任務所取代。并且創建一個執行緒只是為了啟動 aSystem.Timers.Timer是完全沒用的,因為計時器將在執行緒池上運行滴答事件,而不管啟動它的執行緒是什么。至少除非指定了同步物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/480460.html
下一篇:混合2個長度不同的字串?[復制]
