【问题标题】:No UI Thread methods: InvalidOperationException没有 UI 线程方法:InvalidOperationException
【发布时间】:2019-10-29 21:21:50
【问题描述】:

我在 WPF 项目中遇到了 UI 问题。

概念:

C# 中的两个客户端通过聊天与 Linux 上的 Java 服务器进行通信。

对于其中一个客户,我可以使用“/kick [user] [reason]”来踢另一个聊天。为了从发送方接收到被踢用户的套接字,我处于异步回调中,所以 我很少在 UI 线程中工作。 所以为了解决无 ui 方法问题,我使用了 Dispatcher。所以为了关闭当前的用户界面,我会这样做

this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { this.Close(); });

它运行良好,但现在 我需要调用另一个 UI(用户的连接菜单),但是当我使用“Show()”方法时,我得到了

   'System.InvalidOperationException' in PresentationCore.dll
   at System.Windows.Input.InputManager..ctor()
   at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
   at System.Windows.Input.KeyboardNavigation..ctor()
   at System.Windows.FrameworkElement.FrameworkServices..ctor()
   at System.Windows.FrameworkElement.EnsureFrameworkServices()
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Control..ctor()
   at System.Windows.Window..ctor()

所以我也试着把它放在 Dispatcher 中

 MainWindow mw = new MainWindow();
 mw.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });

但我得到同样的错误(System.InvalidOperationException)

怎么做???

方法:

收到的数据包:(不是很有用,但也许我可以通过其他方式做到这一点......?

    private void callBack(IAsyncResult aResult)
    {
        String message = "";
        try
        {
            int size = sck.EndReceiveFrom(aResult, ref ip);
            if (size > 0)
            {
                byte[] receive = new byte[1024];
                receive = (byte[])aResult.AsyncState;
                message = Encoding.Default.GetString(receive, 0, 1024);
                //class for execute sockets informations that the server sends
                new Event(message, this);
            }
            byte[] buffer = new byte[1024];
            //restart async task
            sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ip, new AsyncCallback(callBack), buffer);
        }
        catch (Exception) { }
    }

kickUser:

    public void kickUser(String sender, String reason)
    {
        if (!CheckAccess())
        {
            //working well
            this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { this.Close(); });
            //And here the System.InvalidOperationException
            MainWindow mw = new MainWindow();
            mw.Show();
            //this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });
            //mw.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate { mw.Show(); });
            //All do the same OperationException error.
        }
        MessageBox.Show("You get kicked by \"" + sender + "\" for: " + reason, "Server: /kick");
    }

【问题讨论】:

  • 您得到异常的原因与任何人所做的相同:您试图访问线程中的对象,而不是拥有它的线程。请参阅建议的副本。在这种情况下,您正在后台线程中创建窗口(因此后台线程拥有它),然后尝试在主 UI 线程中显示它。您还需要在主 UI 线程中创建窗口。

标签: wpf multithreading asynchronous dispatcher invalidoperationexception


【解决方案1】:

是的,我发现了问题!

我只需要创建一个在新的主 UI 线程中显示窗口的方法。之后,我只需要在关闭旧 UI 的委托中调用此方法。

     this.Dispatcher.BeginInvoke((System.Threading.ThreadStart)delegate
     {
         MainWindow mw = new MainWindow();
         mw.call();
         this.Close();
     });

这里是MainWindow类中的调用方法(新建UI主线程);

    public void call()
    {
        this.Show();
        MessageBox.Show("You get kicked by \"" + "sender" + "\" for: " + "reason", "Server: /kick");
    }

【讨论】:

    猜你喜欢
    • 2015-10-24
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    相关资源
    最近更新 更多