所以我有这个 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
方法或类似方法中的并发线程?
提前致谢!
这是单线程
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;
}
}
}