如何在C#中跨线程同步这个锁
how to synchronize this lock across thread in C#
我有以下代码:
private static async Task SaveAsync()
{
if (Monitor.TryEnter(_SaveLock, 1000))
{
try
{
Logging.Info(" writing bitmex data to database");
await SomelenghthyDbUpdate1.ConfigureAwait(false);
await SomelenghthyDbUpdate2.ConfigureAwait(false);
await SomelenghthyDbUpdate3.ConfigureAwait(false);
await SomelenghthyDbUpdate4.ConfigureAwait(false);
}
finally
{
Monitor.Exit(_SaveLock);
}
}
}
首先,ConfigureAwait false 与 true 确实产生了真正的速度差异。
因此,知道 finally 部分可以在调用者之外的另一个线程中执行,释放锁时就会出现问题。
我试图防止两个保存操作同时发生,因为它们是事件驱动的,并且可以在需要时跳过,因为它们会定期发生。
我考虑的另一个选择是制作一个任务数组,然后在调用者线程中执行 Task.WaitAll(tasks)。在那种情况下,是否保证我在退出时仍会在同一个线程上?
但是这个问题有一个干净的解决方案吗?也许通过锁设置标志?
根据Docs "The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods."
private static SemaphoreSlim sem = new SemaphoreSlim(1);
private static async Task SaveAsync()
{
if(await sem.WaitAsync(TimeSpan.FromSeconds(1))) // Can be pimped with cancel token
{
try
{
Logging.Info(" writing bitmex data to database");
await SomelenghthyDbUpdate1.ConfigureAwait(false);
await SomelenghthyDbUpdate2.ConfigureAwait(false);
await SomelenghthyDbUpdate3.ConfigureAwait(false);
await SomelenghthyDbUpdate4.ConfigureAwait(false);
}
finally
{
sem.Release();
}
}
}
我有以下代码:
private static async Task SaveAsync()
{
if (Monitor.TryEnter(_SaveLock, 1000))
{
try
{
Logging.Info(" writing bitmex data to database");
await SomelenghthyDbUpdate1.ConfigureAwait(false);
await SomelenghthyDbUpdate2.ConfigureAwait(false);
await SomelenghthyDbUpdate3.ConfigureAwait(false);
await SomelenghthyDbUpdate4.ConfigureAwait(false);
}
finally
{
Monitor.Exit(_SaveLock);
}
}
}
首先,ConfigureAwait false 与 true 确实产生了真正的速度差异。 因此,知道 finally 部分可以在调用者之外的另一个线程中执行,释放锁时就会出现问题。
我试图防止两个保存操作同时发生,因为它们是事件驱动的,并且可以在需要时跳过,因为它们会定期发生。
我考虑的另一个选择是制作一个任务数组,然后在调用者线程中执行 Task.WaitAll(tasks)。在那种情况下,是否保证我在退出时仍会在同一个线程上?
但是这个问题有一个干净的解决方案吗?也许通过锁设置标志?
根据Docs "The SemaphoreSlim class doesn't enforce thread or task identity on calls to the Wait, WaitAsync, and Release methods."
private static SemaphoreSlim sem = new SemaphoreSlim(1);
private static async Task SaveAsync()
{
if(await sem.WaitAsync(TimeSpan.FromSeconds(1))) // Can be pimped with cancel token
{
try
{
Logging.Info(" writing bitmex data to database");
await SomelenghthyDbUpdate1.ConfigureAwait(false);
await SomelenghthyDbUpdate2.ConfigureAwait(false);
await SomelenghthyDbUpdate3.ConfigureAwait(false);
await SomelenghthyDbUpdate4.ConfigureAwait(false);
}
finally
{
sem.Release();
}
}
}