6

我有一个表格。

在这种形式中,我在一个新线程上创建了一个类的实例,因为它运行了一些长时间运行的逻辑。该表单还使用户能够取消此逻辑/线程。

如果需要输入,该类会打开一个新表单。

新表格有时会出现在其他表格的后面。

我在类上设置了一个属性:

public Form ParentForm{get;set;}

我现在可以这样做:

MyForm form = new MyForm();
form.ShowDialog(ParentForm);

但是我在调​​用时遇到了跨线程异常ShowDialog(ParentForm)

我知道我可以InvokeRequired以某种方式使用,但不确定如何在属性上使用。

谢谢

更新:尝试过这样做但仍然出现异常:

MyForm form = new MyForm();
form.ShowDialog(GetParentForm()); 



private Form GetParentForm()
{
    //You have to Invoke() so you can wait for the function to return and obtain its return value.
    if (ParentForm.InvokeRequired)
    {
        return (Form)ParentForm.Invoke(new Func<Form>(() => GetParentForm()));
    }
    else
    {
        return ParentForm;
    } 
}
4

2 回答 2

1

您更新的方法 ( GetParentForm) 将不起作用,因为您将获取引用的任务包装ParentForm在一个InvokeRequired块中。您可以尝试将调用包装ShowDialog在这样的块中,但我认为您仍然会收到跨线程错误。

您最简单的解决方法是将创建和显示第二种形式的代码移出您的类并移入ParentForm. 所以代替这个:

MyForm form = new MyForm();
form.ShowDialog(ParentForm);

你会这样做:

ParentForm.showMyNewForm();

ParentForm会有这个:

public void showMyNewForm()
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}

如果MyForm需要引用另一个线程上的类,您只需添加一个参数,showMyNewForm()以便可以传入对它的引用。

您在此处尝试执行的操作(创建和显示在不同线程上创建的相关、连接的表单)实际上违背了表单在 .NET 中的使用方式。

于 2012-06-19T10:53:24.670 回答
0

您可以将异步方法添加到表单。让我们这样说:

public class MyForm : Form
{
    public void ShowModalAsync()
    {
        this.Invoke(new Action(()=> {
              ShowDilaog(..);
        }));  
    }
}

并使用它,例如:

MyForm form = new MyForm();
form.ShowModalAsync(...);

应该为你工作。

顺便说一句,如果您的问题只是窗口出现在其他人的后面,请尝试使用Form.TopMost属性将其设置为true. 请记住,是的,它将把它带到其他形式的前面,但没有必要在其他最顶层的形式前面。

于 2012-06-19T09:33:55.980 回答