如何使用来自多个线程的async / await以线程安全的方式异步写入文件流

时间:2014-08-05 03:54:03

标签: c# .net multithreading asynchronous async-await

我有一个非常简单的日志记录实用程序,当前是同步的。它从UI(WPF)和线程池线程(Task.Run)调用,并使用lock(_stream){_stream.WriteLine(message);}来保证线程安全。我想添加一个异步写入方法,但不知道如何使其成为线程安全的。

  1. 以下异步方法是否有效?
  2. 它是否会与现有的同步方法相得益彰,它们可以一起使用吗?
  3. 假设前一个问题已经解决,那么最终的Debug.WriteLine是应该进入try区块还是在finally之后 - 它是否会产生影响?
  4. private static SemaphoreSlim _sync = new SemaphoreSlim(1);    
    
    public static async Task WriteLineAsync(string message)
    {
        if (_stream != null)
        {
            await _sync.WaitAsync();
    
            try
            {
                await _stream.WriteLineAsync(string.Format("{0} {1}", DateTime.Now.ToString("HH:mm:ss.fff") + message));
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            finally
            {
                _sync.Release();
            }
    
            Debug.WriteLine("{0} {1}", DateTime.Now.ToString("HH:mm:ss.fff"), message);
        }
    }
    

1 个答案:

答案 0 :(得分:5)

  

以下异步方法是否有效?

如果流设置正确,那么是的,我认为没有理由不这样做

  

它是否能与现有的同步方法一起使用,它们可以一起使用吗?

如果您的同步方法使用相同的SemaphoreSlim并使用同步Wait,那么它们应该很好地匹配。

  

假设前面的内容已经解决,那么最终的Debug.WriteLine应该在try块内部还是在finally块的当前位置之后 - 它会有所作为吗?

如果当且仅当流成功将消息写入流时才应写入调试消息,则在调用try之后,该消息应位于WriteLineAsync块内。