如何防止处理多个GestureRecognizers.Tapped事件

问题描述 投票:0回答:1

所以我有这个 MAUI 应用程序,它允许用户点击边框内部来加载一些数据并打开另一个 ContentPage。为了处理用户的点击,我向边框添加了一个 GestureRecognizer,如下所示:

<Border>
  <Border.GestureRecognizers>
    <TapGestureRecognizer Tapped="HandleBorderTapped"/>
  </Border.GestureRecognizers>
</Border>

HandleBorderTapped
方法如下所示:

private async void HandleBorderTapped(object sender, TappedEventArgs e)
{
  await LoadSomeDataAsync().ConfigureAwait(true);
  await Shell.Current.GoToAsync("Another ContentPage").ConfigureAwait(true);
}

现在,

LoadSomeDataAsync
方法需要几秒钟的时间,不耐烦的用户可能会在边框内多次点击。不幸的是,这会导致应用程序多次打开 ContentPage,从而导致导航堆栈中包含许多这样的 ContentPage。我想避免这种情况。

我尝试通过添加如下布尔值来阻止第二次点击处理:

private volatile bool isLoading;

private async void HandleBorderTapped(object sender, TappedEventArgs e)
{
  if (isLoading)
    return;

  isLoading = true;

  await LoadSomeDataAsync().ConfigureAwait(true);
  await Shell.Current.GoToAsync("Another ContentPage").ConfigureAwait(true);

  isLoading = false;
}

这有帮助,但并不能完全解决我的问题。现在,如果我点击 5 次,ContentPage 只会打开两次,而不是 5 次。不过,ContentPage 应该只打开一次...

谁能告诉我如何防止手势识别器识别多次点击?或者如何限制我的

HandleBorderTapped
方法或类似方法中的并发线程?

提前致谢!

c# asynchronous async-await maui
1个回答
-1
投票

这是单线程

HandleBorderTapped
方法和一些人体工程学的组合。一方面,信号量可以防止重入,这与布尔标志所做的不同,但线程方面更强大一些。但如果您还没有这样做,请通过旋转忙碌指示器让用户知道您“第一次听到他们”。我认为在一起你可能会看到它的行为有所改善。

SemaphoreSlim _sslimOnce = new SemaphoreSlim(1, 1);
private async void HandleBorderTapped(object sender, TappedEventArgs e)
{
    if(_sslimOnce.Wait(0))
    {
        try
        {
            // Spin a cursor to let the user know to be patient
            Busy = true;
            await LoadSomeDataAsync().ConfigureAwait(true);
            await Shell.Current.GoToAsync("Another ContentPage").ConfigureAwait(true);
        }
        catch (Exception ex)
        {
            Debug.Assert(false, ex.Message);
        }
        finally
        {
            _sslimOnce.Release();
            Busy = false;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.