gpt4 book ai didi

c# - 异步/等待中的重入?

转载 作者:太空狗 更新时间:2023-10-29 23:06:14 25 4
gpt4 key购买 nike

我有一个按钮,它有一个 async 处理程序,它调用 async 方法等待。这是它的样子:

private async void Button1_OnClick(object sender, RoutedEventArgs e)
{
await IpChangedReactor.UpdateIps();
}

这是 IpChangedReactor.UpdateIps() 的样子:

public async Task UpdateIps()
{
await UpdateCurrentIp();
await UpdateUserIps();
}

它一直是异步的。
现在我有一个 DispatcherTimer,它在其 tick 事件中重复调用 await IpChangedReactor.UpdateIps

假设我点击了按钮。现在事件处理程序等待 UpdateIps 并返回给调用者,这意味着 WPF 将继续做其他事情。同时,如果计时器触发,它将再次调用 UpdateIps,现在这两种方法将同时运行。所以我的看法是它类似于使用 2 个线程。竞争条件会发生吗? (我的一部分说不,因为它们都在同一个线程中运行。但这很困惑)

我知道异步方法不一定在单独的线程上运行。但是,在这种情况下,它非常令人困惑。

如果我在这里使用同步方法,它会按预期工作。计时器滴答事件仅在第一次调用完成后运行。

谁能教教我?

最佳答案

由于这两个调用都在 UI 线程上运行,因此代码在传统意义上是“线程安全的”——不会有任何异常或损坏的数据。

但是,是否存在逻辑竞争条件?当然。您可以轻松拥有此流程(或任何其他流程):

UpdateCurrentIp() - button
UpdateCurrentIp() - Timer
UpdateUserIps() - Timer
UpdateUserIps() - button

从方法名称来看,这似乎不是真正的问题,但这取决于这些方法的实际实现。

通常,您可以通过使用 SemaphoreSlimAsyncLock ( How to protect resources that may be used in a multi-threaded or async environment? ) 同步调用来避免这些问题:

using (await _asyncLock.LockAsync())
{
await IpChangedReactor.UpdateIps();
}

但在这种情况下,似乎只要避免在当前正在运行的情况下启动新更新就足够了:

if (_isUpdating) return;

_isUpdating = true;
try
{
await IpChangedReactor.UpdateIps();
}
finally
{
_isUpdating = false;
}

关于c# - 异步/等待中的重入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35419752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com