Reputation: 721
I have a Windows Service running that is event driven and each event is handled by its own thread. Now the events are usually coming at a rate of around 10 per second. Last action of the event is to save data to a database.
If saving the data fails, because a connection cannot be established to the Database, I want the first thread that encounters this problem to start a new reconnecting Task running at some interval (e.g. every 30 seconds). Any following threads I wish to simply end. There should be only one reconnecting Task running at any time.
How do I code so that the following event threads safely know that there is already a reconnection Task running and end it's life? Maybe there is a good design pattern for this?
EDIT: Following FelixD's suggested links: Does cancelling a cancellation token trigger an exception in the Task?
If so, I could probably catch the exception, so it would save the incoming data in a file rather than commit it to the database. I have tried to search for this, but it is not clear to me what happens when a Task is cancelled.
Upvotes: 0
Views: 267
Reputation: 134005
I suggest creating a BlockingCollection, and a single worker thread that continually monitors it. When one of your receiver threads gets a message, it processes the message and then, rather than trying to write it to the database, writes it to the BlockingCollection
.
The worker thread that monitors the BlockingCollection
can have a single persistent connection to the database, and can write individual records, or batch them to do a bulk update, or write the records to a file if the database connection fails for some reason.
This kind of thing is easy enough to set up working directly with BlockingCollection
, or you can use TPL Dataflow.
Upvotes: 2
Reputation: 14334
Loss of connection a database is usually described as a transient fault. Often it occurs because the database cannot service the traffic that is being thrown at it, so it starts rejecting or timing out connections.
Have you actually observed this fault occurring or are you pre-empting it?
You should handle a transient fault by waiting for a period and then retrying the operation a number of times, including opening a new connection. Do this for all threads. If all retries fail, be prepared to fall back to a known state and return an error.
I find Polly (by the .Net foundation) to be very useful for handling this behaviour in structured way. http://www.thepollyproject.org/
Upvotes: 0