c# - 当 Interaction.Handle 接收到重复值时,命令引发异常
问题描述
我在我的视图模型中实现了以下方法
private async Task OpenAudioFileImpl ()
{
await OpenFileInteraction.Handle(FileTypes.Audio)
.Where(fp => !string.IsNullOrWhiteSpace(fp))
.Where(fp => fp != AudioFilePath)
.Where(fp => File.Exists(fp))
.Log(this, $"New audio file path selected")
.Select(x => AudioFilePath = x);
}
它通过以下命令调用:OpenAudioFile = ReactiveCommand.CreateFromTask(async _ => await OpenAudioFileImpl());
在我的视图中注册的处理程序打开一个Microsoft.Win32.OpenFileDialog
,所以我可以选择我想要的文件。
我的目标是仅在AudioFilePath
选择新文件并且该文件实际存在时才具有更新值。当我单击按钮时,对话框会正确打开。只要我每次选择不同的文件,我就不会收到错误并AudioFilePath
正确更新。但是,如果我再次选择相同的文件或取消对话框,该命令将引发异常。我做了一些控制台输出,我很确定问题出在这个方法上,我只是不知道它是什么。
因为它是引发错误的 ReactiveCommand,所以我知道处理它的唯一方法是:
OpenAudioFile.ThrownExceptions.Subscribe(ex =>
{
this.Log().Error("OpenAudioFile failed to execute.", ex);
});
我得到的输出是
Exception thrown: 'System.InvalidOperationException' in System.Reactive.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
MainWindowViewModel: OpenAudioFile failed to execute.
这并没有给我太多信息。
解决方案
在这些情况下出现异常的原因是因为您使用的是异步等待。等待 observable 的行为是返回最后一个元素(在 OnCompleted 之前),或者抛出观察到的 OnError。但是,如果序列不包含任何元素,您将收到 InvalidOperationException。所以那些 Where 语句正在过滤掉唯一发出的元素。
在使用 Rx 时,我更喜欢尽可能避免 asnyc/await。但是如果你想坚持使用 async/await,你只需要稍微修改一下你的逻辑。例如,可能会删除 Where 语句并在 Select 中进行条件赋值并在其他地方进行验证。不确定您的整体设置,所以也许您可以想出更好的方法。
推荐阅读
- python - 如何在 Python 中创建合适的方法来读取员工信息
- java - 如何从选项集合中获取数据?
- php - 将客户端时间作为 TIMESTAMP 从 PHP 获取到 SQL
- angularjs - 在 AngularJS 中使用 Google Drive API 进行身份验证
- python - 使用 Python 2 和 3 但找不到 python 2 包
- sql - 我应该保留 2 个视图,还是可以合并为 1 个?
- python-2.7 - 如何从另一个脚本同时运行四个 Python 脚本
- excel - 如何在excel中恰好有7个字符的字符串末尾添加一个X
- excel - Excel:单词完成后重复 VBA 脚本
- r - gganimate:使点在前后停留几帧