在c#中使用IProgressDialog进行线程化

时间:2012-06-05 07:13:02

标签: c# multithreading invoke

我想在我的c#应用程序中添加原生窗口 ProgressDialog 。 为了更好地控制,我定义了一个 OnUserCancled 事件。 在 ShowDialog()从主窗体调用之后, ProgressDialog 类启动一个线程,检查本机 ProgressDialog 是否被取消。但问题是 IProgressDialog 属于主线程,无法从checker线程访问。错误很严重:

  

无法将“WindowsDialogs.Invokes.Interfaces.IProgressDialogC”类型的COM对象转换为接口类型“WindowsDialogs.Invokes.Interfaces.IProgressDialog”。此操作失败,因为由于以下错误,对IID为“{EBBC7C04-315E-11D2-B62F-006097DF5BD4}”的接口的COM组件的QueryInterface调用失败:不支持此类接口(HRESULT异常:0x80004002(E_NOINTERFACE))

我想知道有没有办法将我的命令调用到主类(例如.net表格中的 Invoke()方法。)

注意:Timer类有同样的问题......

2 个答案:

答案 0 :(得分:0)

您应该对该UI中的进度对话框进行所有调用。 在WPF中我做:

Dispatcher.Invoke((Action)delegate()
{
    _progressDialog.SetProgress(percentComplete, 100);
});

对于WinForms,我猜这将是Control.Invoke: http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

答案 1 :(得分:0)

正如@karlas所指出的,这是跨线程调用的问题。

以下是我使用内部计时器定期监控取消按钮状态的解决方案:

private void _timerCallback(object state)
{
    _parentForm.Invoke((Action) delegate {
        try
        {
            if (HasUserCancelled)
            {
                Cancelled?.Invoke(this, EventArgs.Empty);
            }
        }
        catch (Exception)
        {
            // Swallow
        }
    });
}

_parentForm方法中设置Show()字段的位置如下:

public void Show(IWin32Window parent){
    if (_parentForm == null)
        _parentForm = Form.ActiveForm;
    ...
}