【问题标题】:Setting the main window as a dialog owner (message box) called from a STA thread将主窗口设置为从 STA 线程调用的对话框所有者(消息框)
【发布时间】:2013-12-15 12:21:53
【问题描述】:

这是一个调用自定义 C# 消息框的函数。该函数是从一个模拟进程中调用的,该进程在一个不是 UI 线程的线程内运行。

public Output.ButtonResult msgboxYesNo(string Text, string title) {
    Output.Message_Box msg = new Output.Message_Box();

    msg.Dispatcher.Invoke(new Action(() => {
        msg.seeQuestion(Text, title);
        msg.Topmost = true;
        Application.Current.MainWindow.Dispatcher.Invoke(new Action(()
                          => { msg.Owner = Application.Current.MainWindow; }));
        msg.ShowDialog();                
    }));

    return msg.result;
}

有问题的行是这一行:

Application.Current.MainWindow.Dispatcher.Invoke(new Action(() =>
                              { msg.Owner = Application.Current.MainWindow; }));

它抛出这个:

调用线程无法访问该对象,因为不同的 线程拥有它

因为我想将主窗口设置为自定义消息框的所有者,在单独的线程中调用。

如何将主窗体设置为消息框的所有者?

(我希望我把问题解释得足够清楚,表格是 WPF)

【问题讨论】:

    标签: c# wpf multithreading


    【解决方案1】:

    Output.Message_Box 是一个 UI 组件,因此它只能从 UI 线程创建,而不是从后台线程创建。

    您的代码有问题 -

    msgcreated on background thread,但您在这里尝试 access it from UI thread

    msg.Owner = Application.Current.MainWindow;
    

    你甚至应该create message box on UI thread only:

    Application.Current.Dispatcher.Invoke(new Action(() =>
    {
        Output.Message_Box msg = new Output.Message_Box();
        msg.seeQuestion(Text, title);
        msg.Topmost = true;
        msg.Owner = Application.Current.MainWindow;
        msg.ShowDialog(); 
    
        return msg.result;               
    }));
    

    您还尝试从在 UI 线程上创建的后台线程访问 MainWindow。 如果应用程序仅从主线程启动,您可以获得这样的 UI 调度程序:Application.Current.Dispatcher

    【讨论】:

    • 感谢您的启发,我现在已经清楚了!我要补充一点,我无法在调度程序内部进行返回,我必须进行变量赋值,然后在其外部进行返回。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2021-08-07
    相关资源
    最近更新 更多