使用 async/await 时出现 Mutex ApplicationException
Mutex ApplicationException when using async/await
我试图从 url 获得响应,当我在我的函数中使用 await
和 async
时,我的 Mutex
抛出错误。
错误输出:
System.ApplicationException
Object synchronization method was called from an unsynchronized block of code.
at System.Threading.Mutex.ReleaseMutex()
代码:
private async void getData ()
{
_mutex.WaitOne();
try
{
string url = "https://urllink.com";
HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
}
catch (Exception e)
{
// TODO
throw e;
}
_mutex.ReleaseMutex();
}
我建议 两个 三个 修改这里:
- 将
async void
替换为 async Task
(来源:Fildor),并确保 await
它
- 将
Mutex
替换为 SemaphoreSlim
(new SemaphoreSlim(1,1)
与 Mutex
基本相同)——Mutex
文档主要关注“拥有互斥量的线程”,这强烈表明它是线程绑定的,并且 await
与线程绑定场景不兼容; SemaphoreSlim
,但是,不是线程绑定的;此外,它有一个异步感知 WaitAsync()
API,避免线程块(即用 await _semaphore.WaitAsync();
替换 _mutex.WaitOne();
)
- 将释放放在
finally
中,这样即使在失败的情况下也会释放
但是“1”似乎才是真正的问题所在。我还推测这段代码在更改为 async
.
之前工作正常
您也可以删除 catch
,因为只有 throw
的 catch
是多余的;一个只有 throw e;
的 catch
比冗余 更糟:它破坏了堆栈跟踪。
我试图从 url 获得响应,当我在我的函数中使用 await
和 async
时,我的 Mutex
抛出错误。
错误输出:
System.ApplicationException
Object synchronization method was called from an unsynchronized block of code.
at System.Threading.Mutex.ReleaseMutex()
代码:
private async void getData ()
{
_mutex.WaitOne();
try
{
string url = "https://urllink.com";
HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
}
catch (Exception e)
{
// TODO
throw e;
}
_mutex.ReleaseMutex();
}
我建议 两个 三个 修改这里:
- 将
async void
替换为async Task
(来源:Fildor),并确保await
它 - 将
Mutex
替换为SemaphoreSlim
(new SemaphoreSlim(1,1)
与Mutex
基本相同)——Mutex
文档主要关注“拥有互斥量的线程”,这强烈表明它是线程绑定的,并且await
与线程绑定场景不兼容;SemaphoreSlim
,但是,不是线程绑定的;此外,它有一个异步感知WaitAsync()
API,避免线程块(即用await _semaphore.WaitAsync();
替换_mutex.WaitOne();
) - 将释放放在
finally
中,这样即使在失败的情况下也会释放
但是“1”似乎才是真正的问题所在。我还推测这段代码在更改为 async
.
您也可以删除 catch
,因为只有 throw
的 catch
是多余的;一个只有 throw e;
的 catch
比冗余 更糟:它破坏了堆栈跟踪。