我正在尝试创建一个小的 rx 异常处理代码块,我希望在其中获得在特定情况下显示的相同异常。
实际用例是我有一个按钮,它尝试从剪贴板获取数据,用户可能有权访问,也可能无权访问,这将导致引发 SecurityException。
还有可能发生其他一些异常,我也想处理(尽管向用户显示不同的错误消息)。
流本身也有可能出现问题,我想在订阅者的 OnError 方法中处理。
这是我到目前为止所拥有的(请注意,我使用 TextBox 来模拟剪贴板上的文本,并使用复选框来模拟是否应该引发 SecurityException)
private Subject<bool> simulatedPasteCommandSubject = new Subject<bool>();
private readonly CompositeDisposable disposables = new CompositeDisposable();
public Form1()
{
InitializeComponent();
WireUpSimulatedPasteCommandSubject();
}
private Func<IObservable<string>> ObserverableFactory
{
get
{
return () =>
{
return Observable.Defer(() =>
{
return simulatedPasteCommandSubject
.Select(_ => this.GetText())
.Where(x => !string.IsNullOrWhiteSpace(x))
.TrySelect<string, string>(this.TrySelectClipboardData);
});
};
}
}
private void WireUpSimulatedPasteCommandSubject()
{
var clipboardStream = ObserverableFactory();
this.disposables.Add(clipboardStream
.Catch((SecurityException ex) =>
{
this.ShowError("SecurityException");
return ObserverableFactory();
})
.Catch((Exception ex) =>
{
this.ShowError("Exception");
return ObserverableFactory();
})
.Do(data => LogData(data))
.Subscribe(
data => this.ImportTheClipboardData(data),
ex => this.ShowError("Something very bad happened")));
}
private void ImportTheClipboardData(string data)
{
MessageBox.Show(string.Format("Importing Clipboard data\r\n {0}", data));
}
private string GetText()
{
if (chkShouldThrow.Checked)
throw new SecurityException("SecurityException");
// simulate text coming from Clipboard
return textBox1.Text;
}
private void button1_Click(object sender, EventArgs e)
{
simulatedPasteCommandSubject.OnNext(true);
}
private bool TrySelectClipboardData(string dataIn, out string dataOut)
{
dataOut = string.Join("", dataIn.Reverse());
return true;
}
private void LogData(string data)
{
string dataLog = string.Format("Data : {0}", data);
Debug.WriteLine(dataLog);
}
private void ShowError(string ex)
{
string error = string.Format("Error : {0}", ex);
MessageBox.Show(error);
}
抱歉,列表太大了。问题是,如果我在 TextBox 中键入一些文本(以模拟剪贴板)然后单击按钮(这是模拟用户会做什么,这使得剪贴板流产生 (OnNext)),我得到了我所期望的。在这种情况下,一个简单的反转字符串。
但是,如果我单击应该模拟引发 SecurityException 的 CheckBox,然后单击按钮(这是模拟用户将执行的操作,这使得剪贴板流产生(OnNext)),我确实捕获了 SecurityException,并看到记录。到目前为止一切都很好
当我尝试使用 CheckBox 再次单击该按钮时,问题就出现了,该 CheckBox 应该模拟引发的 SecurityException 仍然处于选中状态。然后我得到以下
“例外”
然后,当我尝试使用应模拟引发 SecurityException 的 CheckBox 再次单击该按钮时,仍处于选中状态。然后我得到以下
“发生了非常糟糕的事情”
当我期望看到的是“SecurityException”每次都被捕获时,因为这是第一次。
我有一种感觉,这与返回的相同流有关,该流以前在“SecurityException”的捕获中