user1713059
user1713059

Reputation: 1507

Async queue return info

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

Answers (1)

Stephen Cleary
Stephen Cleary

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

Related Questions