当前位置:网站首页>Timing manager based on C #
Timing manager based on C #
2022-07-05 03:39:00 【Dotnet cross platform】
problem
We will encounter the following problems when using various systems :
12306 Buy train tickets on if 15 If the payment is not completed within minutes, the order will be automatically cancelled .
Reserved seats in the conference venue , If 10 If the payment is not completed within minutes, the reservation will be automatically cancelled .
After the specified time , I need to perform a task .
I have done many systems before , It is often a specific task that is performed on a regular basis . And the appeal problem involves the timing task of sliding window time .
such as : I am in the morning 10 spot 20 I booked a train ticket separately , I need to 15 Pay in minutes , Otherwise, the order will be canceled . Hundreds of people may book other train tickets at the same time , I need to be in everyone's 15 Check when the minute deadline expires , If it has not been paid, the order will be cancelled automatically .
programme
After we figure out the problem to be solved , Let's think about the plan . Experienced programmers will immediately think of the following solutions :
Use the delayed delivery function of message queue , Send a delay after each order is successfully added 15 Minute delay message . Order status processor 15 Message received in minutes , Check payment status , If not, cancel the order .
Redis There are similar functions , The principle is roughly the same .
But I don't want to use the function of message queue , Because delayed message delivery is a technical implementation , I hope to use code to reflect this business implementation , So use pure code to deal with him .( I'm not trying to reinvent the wheel , Because this is a business requirement , There will be a need for change and expansion , So I decided to try to increase my experience )
Algorithm ideas :
Our demand timing is 15 Within minutes, , Assume no more than 1 Hours or days .( If exceeded 1 Hour , This design can be extended , This article will not be discussed for the time being )
We can consider dividing an hour into 3600 second , Every second represents a location to store all expired orders , When placing an order, according to the current time add 15 Minute intervals , We can get it 15 Minutes later , Add this order to the corresponding location .
Data structure selection :
We choose C# The latest concurrent dictionary provided in is used as the basic data structure ,Key The value is 3600 The value of each second in seconds , The content is a queue used to store all orders at that point in time .

public ConcurrentDictionary<int, ConcurrentQueue<IJob>> jobs = new ConcurrentDictionary<int, ConcurrentQueue<IJob>>();We have thought about the data structure , In fact, most of the functions are completed , The design of the code is basically settled .
Code implementation ( I like experimenting with console applications )
Set up a timing manager
public class TimerManager { // The concurrent dictionary stores the tasks that need to be checked ( Here can be the order check task , Each task can contain an order Id) public ConcurrentDictionary<int, ConcurrentQueue<IJob>> jobs = new ConcurrentDictionary<int, ConcurrentQueue<IJob>>(); private Timer timer; public TimerManager() { // Every interval 1 Once per second . Synchronize with the current time . timer = new Timer(ProcessJobs, null, 0, 1000); } }Add a task to the dictionary
/// <summary> /// Add a task to the time dictionary /// </summary> /// <param name="timeKey"> Calculated according to the delay time key value </param> /// <param name="duetime"> Millisecond unit </param> /// <exception cref="NotImplementedException"></exception> public void AddJob(IJob job, TimeSpan duetime) { var key = GetKey(duetime); ConcurrentQueue<IJob> queue = new ConcurrentQueue<IJob>(); queue.Enqueue(job); jobs.AddOrUpdate(key, queue, (key, jobs) => { jobs.Enqueue(job); return jobs; }); }Calculate according to time Key Methods
/// <summary> /// Generate the current key value according to the delay time /// </summary> /// <param name="duetime"></param> /// <returns></returns> private int GetKey(TimeSpan duetime) { var currentDateTime = DateTime.Now; // Due time var targetDateTime = currentDateTime.Add(duetime); // Don't forget to convert minutes into seconds , Then add it to the delay time to get Key var key = targetDateTime.Minute * 60 + targetDateTime.Second; return key; }Add tasks to the dictionary
/// <summary> /// Add a task to the time dictionary /// </summary> /// <param name="job"> Tasks to be performed </param> /// <param name="duetime"> How many intervals do you check </param> public void AddJob(IJob job, TimeSpan duetime) { var key = GetKey(duetime); ConcurrentQueue<IJob> queue = new ConcurrentQueue<IJob>(); queue.Enqueue(job); // This is the method of concurrent dictionary , This is when Key If it doesn't exist, add a new value , When Key Existence exists in Key Add a new task to the queue of jobs.AddOrUpdate(key, queue, (key, jobs) => { jobs.Enqueue(job); return jobs; }); }The method of processing tasks when the timer executes every second , Cycle to get tasks from the queue until all tasks are processed .
private async void ProcessJobs(object state) { // Calculate according to the current time Key value var key = DateTime.Now.Minute * 60 + DateTime.Now.Second; Console.WriteLine(key); // lookup Key Value the corresponding task queue and process . bool keyExists = jobs.TryGetValue(key, out var jobQueue); if (keyExists) { IJob job; while(jobQueue.TryDequeue(out job)) { await job.Run(); } } }Design in code IJob and Job An implementation of , For ease of understanding , This job Not doing much . If you need to expand to check the order , You can record the order here Id, When creating a task, place an order ID Associated with the task , In this way, the timer can find the corresponding order when processing this task .
public interface IJob { Task Run(); } /// <summary> /// Represents a job /// </summary> public class Job : IJob { public Guid JobId { get; set; } public Job() { JobId = Guid.NewGuid(); } public async Task Run() { Console.WriteLine(" Job Id: " + JobId.ToString() + " is running."); await Task.Delay(2000); Console.WriteLine(" Job Id:" + JobId.ToString() + " have completed."); } }The main program Programe Call the timing manager
using TimerTest; Console.WriteLine("Hello, World!"); TimerManager timerManager = new TimerManager(); Job job1 = new Job(); // Add a task 1 Execute in minutes timerManager.AddJob( job1, TimeSpan.FromMinutes(1)); // Adding another task in 2 Execute in minutes Job job2 = new Job(); timerManager.AddJob(job2, TimeSpan.FromMinutes(2)); Console.ReadLine();
Execution results
You can see in the results that , Mission 1 stay 1014 Is processed on the key value of ,1014 The time corresponding to the key value of is 16:54 second , That is, when I run this program 1 Minutes later .

| Mission | Add the time | execution time |
|---|---|---|
| First mission ( timing 1 minute ) | 15:54 | 16:54 |
| Second task ( timing 2 minute ) | 15:54 | 17:54 |
Mission 2 stay 1074 Is processed on the key value of ,1074 The corresponding time is 17:54 second perform . It can be seen from the above table that the program runs normally and the result is .

summary
This is a simple console program that verifies the implementation of the timing manager , We will 1 Hours are divided into 3600 second , Every second corresponds to one Key value , On this value, we store the tasks that need to be processed . When adding tasks , We also use the same algorithm to determine this Key value . When processing, divide by... According to the current time Key Value to process .
In this case , In the real world , We have 3600 individual Key Value can store all orders submitted by users every second , Time has not passed 1 I will deal with the corresponding task in seconds .
What can be improved later
We can add this class to ASP.NET MVC in , Use dependency injection for single instance lifecycle , Concurrent dictionaries and queues are thread safe , So you can use it safely .
We can expand Job Method , Add more information according to the business logic to facilitate processing . For example, processing orders ID, Or any other business ID.
The method of processing tasks can adopt multiple consumers to execute concurrently , Increase processing speed .
You can store task entities in the database , In order to deal with sudden downtime accidents, tasks can be rebuilt quickly .
Of course we can use Hangfire To easily realize this business .
var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7)); // Just change this to minutes
Finally, I wish .NET 20 Happy anniversary .
边栏推荐
- [summary of two registration methods]
- 【无标题】
- Assembly - getting started
- How to learn to get the embedding matrix e # yyds dry goods inventory #
- Jd.com 2: how to prevent oversold in the deduction process of commodity inventory?
- Basic knowledge of tuples
- Solve the problem that sqlyog does not have a schema Designer
- Basic authorization command for Curl
- UE4 DMX和grandMA2 onPC 3.1.2.5的操作流程
- Anti debugging (basic principles of debugger Design & NT NP and other anti debugging principles)
猜你喜欢

Clickhouse同步mysql(基于物化引擎)

花了2晚,拿到了吴恩达@斯坦福大学的机器学习课程证书

How to define a unified response object gracefully
![[system security] ten thousand words summary system virtualization container bottom layer principle experiment](/img/c6/1bdb29a0acb0739f67b882fa6b3b47.jpg)
[system security] ten thousand words summary system virtualization container bottom layer principle experiment

Three line by line explanations of the source code of anchor free series network yolox (a total of ten articles, which are guaranteed to be explained line by line. After reading it, you can change the

Pat class a 1162 postfix expression
![[105] Baidu brain map - Online mind mapping tool](/img/4f/64ee0bb15aec435294d4f5fde4493e.jpg)
[105] Baidu brain map - Online mind mapping tool

New interesting test applet source code_ Test available
![[learning notes] month end operation -gr/ir reorganization](/img/4e/9585b7c62527beaa30a74060cb0e94.jpg)
[learning notes] month end operation -gr/ir reorganization

The perfect car for successful people: BMW X7! Superior performance, excellent comfort and safety
随机推荐
Azkaban installation and deployment
【无标题】
Single box check box
问下,这个ADB mysql支持sqlserver吗?
Nmap user manual learning records
Tencent cloud, realize image upload
FBO and RBO disappeared in webgpu
Basic knowledge of tuples
Logstash、Fluentd、Fluent Bit、Vector? How to choose the appropriate open source log collector
MySQL winter vacation self-study 2022 11 (10)
v-if VS v-show 2.0
Kbp206-asemi rectifier bridge kbp206
Cette ADB MySQL prend - elle en charge SQL Server?
Delphi read / write JSON format
Port, domain name, protocol.
Kubernetes - Multi cluster management
Jd.com 2: how to prevent oversold in the deduction process of commodity inventory?
Qrcode: generate QR code from text
Some enterprise interview questions of unity interview
Google Chrome CSS will not update unless the cache is cleared - Google Chrome CSS doesn't update unless clear cache