异步队列返回信息

时间:2015-08-30 15:16:57

标签: c# .net logging asynchronous

您好我正在尝试创建一个将日志发送到WCF的日志系统。原则上它有一个Log(字符串文本)方法,在实际执行日志记录操作之前可以多次调用它以减少网络聊天。为了实现这一点,我创建了一个日志队列(列表)和一个计时器,它以设定的频率执行实际的日志记录。

当我想在程序中记录某些内容时,我使用了Log方法。看起来有点像这样:

    private readonly List<string> _currentLogQueue = new List<string>(); 

    public void Log(string logText)
    {
        lock (_currentLogQueue)
        {
            _currentLogQueue.Add(logText);
        }
    }

然后将队列定期发送到WCF。定期发送完成如下:

    private void SetUpQueue(TimeSpan queueFlushPeriod)
    {
        Task.Run(async () =>
        {
            while (true)
            {
                SendQueue();  // Does the actual communication and clears queue on success.
                await Task.Delay(queueFlushPeriod);
            }
        });
    }

如何使用此记录器启用程序以对SendQueue()期间的错误做出反应?如果需要,我可以修改SendQueue以返回某种错误。现在我只能想到一个委托形式的回调传递给Log()方法,但它似乎非常过时而且在异步等待时代并不好玩。

1 个答案:

答案 0 :(得分:1)

回答你的问题:

可以指示已记录消息成功/失败的TaskCompletionSource

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);
}

但是,我不认为这会有所帮助。如果记录失败,程序可以采取哪些有意义的行动?