我正在使用外部库加载大而复杂的文件。这个库的调用是相当复杂的,所以我把它们包装在一些静态帮助器方法中,这些方法可以很好地处理缓存等问题。然后使用Tasks
在后台运行这些方法。
在加载过程中,库会在某些情况下抛出异常,指出文件块格式错误,因此无法解析。这些异常被认为是“安全的”,并且,如果它们被吞下,库将跳过坏块并愉快地继续解析文件的其余部分。
发生这种情况时,我需要向用户显示一个对话框,询问是否应该中止文件导入。这可以正常工作如下:
public static class MyBigFileLoadMethods {
// private fields for locking, caching, etc.
public static Load(string filePath, bool cache = true) {
// validation etc.
try {
var data = LoadMethodInDll(filePath);
} catch (BadBlockException) {
if (MessageBox.Show("boom. continue anyway?") == DialogResult.Yes) {
// call appropriate dll methods to ignore exception and continue loading
} else {
throw;
}
}
}
}
从设计为在后台运行的方法调用MessageBox.Show()
感觉非常错误,但我还没有想出一个更好的方法,没有涉及如此多的编组和调用代码变得非常难以阅读。有没有更简洁的方法来做这个或更好的方式来设计我的加载过程?
答案 0 :(得分:3)
库执行此操作的适当方法是通过某种回调。最简单的实现是返回bool的委托,指示处理是否应该继续。一个更丰富但更复杂的方法是一个策略接口,有各种方法来实现,指示是继续,中止,重试等。
然后,您的UI代码提供回调,以适当的方式向用户显示消息。加载库的代码如下所示:
public static class MyBigFileLoadMethods {
// private fields for locking, caching, etc.
public static void Load(string filePath, Func<Exception, bool> continueOnException = null, bool cache = true) {
// validation etc.
try {
var data = LoadMethodInDll(filePath);
} catch (BadBlockException e) {
if (continueOnException != null && continueOnException(e)) {
// call appropriate dll methods to ignore exception and continue loading
} else {
throw;
}
}
}
}
然后在您的UI代码中,您将要编组回UI线程。它看起来像这样:
MyBigFileLoadMethods.Load("C:\path\to\data", ShowError);
private bool ShowError(Exception e)
{
if (this.InvokeRequired)
{
return (bool)this.Invoke(new Func<Exception, bool>(ShowError), e);
}
return MessageBox.Show(string.Format("boom: {0}. continue anyway?", e.Message)) == DialogResult.Yes;
}