【发布时间】:2014-08-05 03:54:02
【问题描述】:
我有一个非常简单的日志实用程序,目前是同步的。它从 UI (WPF) 和线程池线程 (Task.Run) 调用,并使用 lock(_stream){_stream.WriteLine(message);} 来保证线程安全。我想添加一个异步写入方法,但不知道如何使它成为线程安全的。
- 以下异步方法是否有效?
- 它与现有的同步方法能否很好地配合使用,它们是否可以毫无问题地一起使用?
- 假设前面的问题已解决,最后的
Debug.WriteLine应该进入try块内还是位于当前所在的finally之后 - 有什么不同吗?
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);
}
}
【问题讨论】:
-
试试
BlockingCollection<T>,它有很多内置功能可以开箱即用。 -
您不应该使用信号量来实现互斥。计数为 1 的信号量与互斥原语(例如
lock)之间存在显着差异。在这里使用lock而不是信号量。如果您认为合适,请使用SpinLock。 -
@JimMischel 我不明白。您不能在
lock内部使用await。那么你将如何异步lock? -
你是对的。我以为
Monitor或SpinLock上有一个TryEnterAsync。
标签: c# .net multithreading asynchronous async-await