Reputation: 1507
Hello I am trying to create a logging system which sends logs to a WCF. In principal it has a Log(string text) method, which can be called multiple times before the actual logging action is made to reduce network chatter. To achieve this I've created a queue (a list) of logs and a timer, which performs the actual logging with a set frequency.
When I want to log something in my program I use the Log method. It looks a bit like this:
private readonly List<string> _currentLogQueue = new List<string>();
public void Log(string logText)
{
lock (_currentLogQueue)
{
_currentLogQueue.Add(logText);
}
}
The queue is then periodically sent to the WCF. The periodic sending is done like so:
private void SetUpQueue(TimeSpan queueFlushPeriod)
{
Task.Run(async () =>
{
while (true)
{
SendQueue(); // Does the actual communication and clears queue on success.
await Task.Delay(queueFlushPeriod);
}
});
}
How can I enable the program using this logger to react to errors during the SendQueue()
? I can modify SendQueue to return some kind of error if needed. Right now I only can think of a callback in the form of a delegate passes to the Log()
method, but it seems very passé and not fun in the age of async await.
Upvotes: 0
Views: 64
Reputation: 456507
To answer your question:
You can have a TaskCompletionSource
indicating success/failure of the logged message:
private readonly List<Tuple<string, TaskCompletionSource<object>> _currentLogQueue = ...;
public Task LogAsync(string logText)
{
var tcs = new TaskCompletionSource<object>();
lock (_currentLogQueue)
{
_currentLogQueue.Add(Tuple.Create(logText, tcs));
}
return tcs.Task;
}
// (Within SendQueue)
var message = queueElement.Item1;
var tcs = queueElement.Item2;
try
{
SendMessage(message);
tcs.TrySetResult(null);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
However, I don't think this would really be helpful. What meaningful action can the program take if logging failed?
Upvotes: 1