问题
I am building a Blazor application with a REST API and Web interface. I will also have a monitoring part of the application that will poll data each second from a lot of different data sources. I have created a long running thread in a separate class that simply polls the data I want and it seems to be working fine. The application template I am using is a Blazor ASP.NET Server application. Simply like this:
m_pollThread = new Thread(new ThreadStart(PollThread))
{
IsBackground = true
};
m_pollThread.Start();
What I am wondering now is: is it completely wrong with respect to programming patterns to put this type of polling threads inside of the Blazor application itself? Is there some problems doing like this that will backfire later on (memory consumption, performance of the rest of the application)? The reason why I am asking is because as far as I know, Blazor and ASP.NET Core applications are general "on-request" and wakes up when something is requested, and not executing long-running endless polling tasks. I do not know if I could run that within IIS for instance.
回答1:
is it completely wrong with respect to programming patterns to put this type of polling threads inside of the Blazor application itself?
Yes. It won't break immediately but it is asking for trouble.
The solution is easy though, ASP.NET core lets you run multiple Host threads very easily.
The new worker template is probably the preferred way now but all you really need is
class MyPollingService : BackgroundService { ... }
and
services.AddHostedService<MyPollingService>();
Your gain is better integration with the framework and more control over Start and Stop etc.
回答2:
I built something similar for Pipeline pressure testing, and I only used one timer to read all of our devices in the test.
I can't post the class because it belongs to my last client, but basically I set a timer to run every 30 seconds (30000 milliseconds), so it is guaranteed to run at least one in a minute with this code:
public int Minute { get; set; }
public bool NewMinute
{
get
{
// initial value
bool newMinute = DateTime.Now.Minute != this.Minute;
// return value
return newMinute;
}
}
Then in my timer tick event, I do a check
if (NewMinute)
{
// store so I don't send again till the next minute
Minute = DateTime.Now.Minute;
// Get all temperature values
GetTemperatureValues();
}
In my GetTemperatureValues method, I call off to some serial libraries, and I either get a value back or if I don't get a response back within 5 seconds, it bails.
Not sure if that gives you any guidance, but it did work for where I used to work, except for they bought the cheapest devices and they failed too often, but not the code.
Now this was all done in Windows Forms, Blazor is a different animal. You can use Timers in Blazor as I do in my Sprite component to animate it, and there is a Subscriber interface included in this Nuget package and sample project:
https://github.com/DataJuggler/DataJuggler.Blazor.Components
And here is a video that goes with it if you are bored: https://youtu.be/frtetHgfdIo
来源:https://stackoverflow.com/questions/60490969/polling-thread-in-blazor