我应该如何从后台线程请求用户输入?

我正在使用外部库加载大型复杂文件.该库的调用相当复杂,因此我将它们包装在几个静态帮助器方法中,这些方法可以很好地为我处理缓存等.然后使用“任务”在后台运行这些方法.

在加载过程中,库在某些情况下会引发异常,指出文件的某个块格式错误,因此无法解析.这些异常被认为是“安全的”,并且如果吞下了它们,库将跳过错误的块并愉快地继续解析文件的其余部分.

发生这种情况时,我需要向用户显示一个对话框,询问是否应中止文件导入.可以正常工作如下:

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()感觉很不对劲,但是我没有想出一种更好的方法,该方法不需要太多的编组和调用,因此代码变得非常困难读书.有没有更清洁的方法来执行此操作,或者有更好的方法来设计加载过程?

解决方法:

库执行此操作的适当方法是通过某种回调.最简单的实现是一个委托返回一个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;
}
上一篇:如何在C#中启动CellContentDoubleClick?


下一篇:我可以将控件移动到组框内而不会丢失控件的属性吗?