我在 MVVM 应用程序中有一个按钮,它连接到视图模型中的命令。视图模型命令的处理程序执行一些文件 I/O(特别是调用 File.Copy 来创建或覆盖现有文件)。
现在,似乎当我双击按钮时,这个命令处理程序被调用了两次。由于两个处理程序现在都试图访问同一个文件以同时复制/覆盖它,我得到了一个 IOException。
除了捕获 IOException 并忽略它之外,还有什么方法可以处理这种情况?尽管系统的其他部分可能存在不相关的问题导致这种情况发生,但这似乎并不能保证捕获。
我在 MVVM 应用程序中有一个按钮,它连接到视图模型中的命令。视图模型命令的处理程序执行一些文件 I/O(特别是调用 File.Copy 来创建或覆盖现有文件)。
现在,似乎当我双击按钮时,这个命令处理程序被调用了两次。由于两个处理程序现在都试图访问同一个文件以同时复制/覆盖它,我得到了一个 IOException。
除了捕获 IOException 并忽略它之外,还有什么方法可以处理这种情况?尽管系统的其他部分可能存在不相关的问题导致这种情况发生,但这似乎并不能保证捕获。
在 ViewModel 中使用一个值来保护发生单击时将运行的代码。设置一个值,如:bool bFileIO = false;
然后在您的处理程序函数中:
if (!bFileIO)
{
bFileIO = true;
//file IO here
bFileIO = false;
}
类似的东西可以防止多次单击尝试运行多次。
执行此操作的最简单方法是在执行时让命令返回 false CanExecute
。这将防止发生第二次点击(因为您的按钮将被禁用)。如果使用DelegateCommand
from prism:
private readonly DelegateCommand<object> copyCommand;
private bool isCopying = false;
public MyViewModel()
{
copyCommand = new DelegateCommand<object>(
_ => !isCopying,
_ =>
{
if (isCopying) return; // this shouldn't be required, but here for safety
isCopying = true;
copyCommand.RaiseCanExecuteChanged();
// do copy
isCopying = false;
copyCommand.RaiseCanExecuteChanged();
});
}
我认为你应该使用你的命令的 CanExecute 来控制你的按钮。
<Button Command="{Binding WriteFileCommand}" Content="Button" Height="23" HorizontalAlignment="Left" Margin="273,194,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
和视图模型
public class MyViewModel
{
private bool isWritingFile = false;
public DelegateCommand WriteFileCommand
{
get;
private set;
}
public bool IsWritingFile
{
get
{
return isWritingFile;
}
set
{
isWritingFile = value;
WriteFileCommand.RaiseCanExecuteChanged();
}
}
public MyViewModel()
{
WriteFileCommand = new DelegateCommand(WriteFile, CanWriteFile);
}
private void WriteFile()
{
IsWritingFile = true;
// write the file
// FileStream stream = new FileStrem(...)
//
IsWritingFile = false;
}
}