【问题标题】:Async queue return info异步队列返回信息
【发布时间】:2015-08-30 15:16:57
【问题描述】:

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

当我想在我的程序中记录一些东西时,我使用 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() 方法的回调,但在异步等待的时代,这似乎很过时且不好玩。

【问题讨论】:

    标签: c# .net logging asynchronous


    【解决方案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);
    }
    

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

    【讨论】:

    • 其实是一个通讯记录器。许多“类型”的类正在同时执行,如果某个类型的日志记录失败(对于该类型是强制性的),则该类型必须停止执行。
    猜你喜欢
    • 2023-02-21
    • 2013-04-12
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2023-03-24
    • 1970-01-01
    相关资源
    最近更新 更多