gpt4 book ai didi

asynchronous - MvvmCross异步命令锁

转载 作者:行者123 更新时间:2023-12-02 03:38:34 29 4
gpt4 key购买 nike

我的应用程序中有很多按钮。它们彼此相邻放置。所有方法都是 IMvxAsyncCommand 类型。经过用户测试后,我发现了一些不匹配的地方。我发现重复的操作 - 几乎同时调用两个不同的按钮。

我所做的就是创建自己的 SafeAsyncCommand 类并继承自 MvxAsyncCommand。我的目标是在执行之间创建延迟 - 我想在低于 0.5 秒的情况下防止给定延迟中的双击。

这是我的工作:

public static class SafeCommandSettings
{
public static bool CanExecute { get; private set; }
public static TimeSpan Delay => TimeSpan.FromMilliseconds(500);

static SafeCommandSettings()
{
CanExecute = true;
}

public static async void Pause()
{
if (!CanExecute) return;

CanExecute = false;
await Task.Delay(Delay);
CanExecute = true;
}
}

public class SafeAsyncCommand : MvxAsyncCommand
{
public SafeAsyncCommand(Func<Task> execute, Func<bool> canExecute = null, bool allowConcurrentExecutions = false)
: base(execute, canExecute, allowConcurrentExecutions)
{
}

public SafeAsyncCommand(Func<CancellationToken, Task> execute, Func<bool> canExecute = null, bool allowConcurrentExecutions = false)
: base(execute, canExecute, allowConcurrentExecutions)
{
}

protected override async Task ExecuteAsyncImpl(object parameter)
{
if (!SafeCommandSettings.CanExecute) return;

SafeCommandSettings.Pause();
await base.ExecuteAsyncImpl(parameter);
}
}

public class SafeAsyncCommand<T> : MvxAsyncCommand<T>
{
public SafeAsyncCommand(Func<T, Task> execute, Func<T, bool> canExecute = null, bool allowConcurrentExecutions = false)
: base(execute, canExecute, allowConcurrentExecutions)
{
}

public SafeAsyncCommand(Func<T, CancellationToken, Task> execute, Func<T, bool> canExecute = null, bool allowConcurrentExecutions = false)
: base(execute, canExecute, allowConcurrentExecutions)
{
}

protected override async Task ExecuteAsyncImpl(object parameter)
{
if (!SafeCommandSettings.CanExecute) return;

SafeCommandSettings.Pause();
await base.ExecuteAsyncImpl(parameter);
}
}

我认为这可行,但我看到用户能够再次执行此操作。我是否错过了一些有关异步方法或静态线程安全的知识?

提前致谢

最佳答案

为此,您可以利用 MvxNotifyTask这是 Task 的包装器,用于监视不同的任务状态,您将运行命令并执行类似的操作(请注意,您不需要命令为 MvxAsyncCommand):

public MvxNotifyTask MyNotifyTaskWrapper { get; private set; }

public MvxCommand MyCommand { get; private set; }

private void InitializeCommands()
{
// this command is executed only if the task has not started (its wrapper is null) or the task is not in progress (its wrapper is not IsNotCompleted)
this.MyCommand = new MvxCommand(() => this.MyNotifyTaskWrapper = MvxNotifyTask.Create(() => this.MyLogicAsync()),
() => this.MyNotifyTaskWrapper == null || !this.MyNotifyTaskWrapper.IsNotCompleted);
}

private async Task MyLogicAsync()
{
// my async logic
}

因此,一旦异步进程启动,该命令就无法再次执行,以防止重复操作,并且您可以在该任务完成后再次启动它。

如果您在运行某些任务时必须禁用多个命令执行,只需在不同命令上添加相同的 CanExecute 条件或混合不同 MvxNotifyTask 的条件

还要检查 MvxNotifyTask 是否会引发属性更改通知,您可以在 View 中订阅或绑定(bind)该通知,并在执行操作时显示“正在加载”或类似内容。

注意:如果您使用的是 Mvx < 5.5,则不会有 MvxNotifyTask,但您可以使用 NotifyTaskCompletion由 Stephen Cleary 完成,与 MvxNotifyTask 几乎相同,并且它源自 MvxNotifyTask 的基础。

关于asynchronous - MvvmCross异步命令锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49368786/

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