应用程序冻结后Dispatcher.Invoke [英] App freezes after Dispatcher.Invoke

查看:190
本文介绍了应用程序冻结后Dispatcher.Invoke的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的应用程序中调用任何控制的dispatcher.invoke时冻结。



当我打电话给调度员在单选按钮,网格Image..etc的应用冻结但不给错误。任何帮助,请!谢谢



我所说的线程方法RunClient

 私人无效RunClient ()
{

TcpClient的客户端;

//实例化的TcpClient将数据发送到服务器

{
//第1步:创建TcpClient的,并连接到服务器

客户端=新的TcpClient();
client.Connect(IP,5001);

//第2步:获取的NetworkStream与TcpClient的
输出= client.GetStream有关();

//创建写入和跨流
作家=新的BinaryWriter(输出)读取对象;
=读者新BinaryReader(输出);

串theReply =;


{

{
//读取发送到服务器
theReply = reader.ReadString字符串();

INT I = 0;

的foreach(在theReply.Split变种X('#'))
{
ReadString [I] = X;
I ++;
}

CheckConnection(ReadString [0]);



}
赶上(例外)
{
//什么也不做
}

}而(ReadString [6] .Equals()及与放大器;
connection.Connected);

updatelabel =()=> GameResult(ReadString [6]);
Dispatcher.Invoke(新动作(updatelabel));

如果(connection.Connected!)
{
MessageBox.Show(连接中断比赛将被自动关闭。);
writer.Close();
reader.Close();
output.Close();
的Connection.close();
this.Close();
}

}
//处理异常,如果错误在建立连接
赶上(例外错误)
{
MessageBox.Show(检查Internet连接无法连接)。!;
}


}

在代码进入方法(检查连接),并调用调度应用程序冻结。

 无效CheckConnection(串II)
{

{
如果(ii.Equals(已连接))
{
MessageBox.Show(成立一个Connection);




INT X = Convert.ToInt32(ReadString [1]);

如果(X == 1)
{

updatelabel =()=> char1RadioButton2.IsEnabled = FALSE;
char1RadioButton2.Dispatcher.Invoke(新动作(updatelabel));
}

,否则
{
updatelabel =()=> char5RadioButton2.IsEnabled = FALSE;
char5RadioButton2.Dispatcher.Invoke(新动作(updatelabel));
}


updatelabel =()=> CreatingGameGrid.Visibility = System.Windows.Visibility.Visible;
CreatingGameGrid.Dispatcher.Invoke(新动作(updatelabel));



updatelabel =()=> JoinGameGrid.Visibility = System.Windows.Visibility.Visible;
JoinGameGrid.Dispatcher.Invoke(新动作(updatelabel));

}
,否则
{
MessageBox.Show(没有这样的游戏找到);
this.Close();
}
}
赶上(例外X)
{
MessageBox.Show(x.ToString());
}
}


解决方案

Dispatcher.Invoke尝试的同步上运行调度程序线程指定的操作。



假设RunClient是在调度线程运行,并且同时继续循环,而你正在试图调用回送到Dispatcher线程来运行,呼叫将冻结。



最简单的解决办法是更换所有Dispatcher.BeginInvoke的Dispatcher.Invoke并给它,这将运行一次您的RunClient完成当务之急。



其他的解决办法是在的 BackgroundWorker的



与答案




    类似问题
  1. Dispatcher.Invoke环冻结UI

  2. Dispatcher.Invoke挂起主窗口



回应有关ReadString冻结评论



电话阅读上的NetworkStream是一个阻塞调用。唉,其实,它是通过调用的 TcpClient.GetStream ()的块。在MSDN文档状态的您已经获得的NetworkStream之后,调用Write方法将数据发送到远程主机。调用read方法来接收来自远程主机到达的数据。这两种方法都被阻塞,直到指定的操作被执行的'。



我用 dotPeek 来看看有什么ReadString在做,它做的第一件事是读取使用的 NetworkStream.ReadByte 这将阻止,直到它有一个数值来读取。



这意味着ReadString会坐在那里直到有可供读取的数据和数据的量相同或比预期更。您将需要检查,如果您有任何调用的 stream.DataAvailable 或的 reader.PeekChar



另外,你可以在一个单独的线程中运行你的套接字代码。如果您正在使用.NET 4.5,我会采取在href=\"http://msdn.microsoft.com/en-us/library/dd537609.aspx\">任务并行库的 ntziolis 说,在回答这个的我们已经与(长天被而非数分钟或数小时),取得了良好的经验>问题的。


I have this application that freezes when calling the dispatcher.invoke for any control.

When i Call the Dispatcher in radiobutton, Grid, Image..etc the App freezes but without giving errors. any help please !!! thank you

I call the thread Method RunClient

private void RunClient()
    {

        TcpClient client;

        // instantiate TcpClient for sending data to server
        try
        {
            // Step 1: create TcpClient and connect to server

            client = new TcpClient();
            client.Connect(ip, 5001);

            // Step 2: get NetworkStream associated with TcpClient
            output = client.GetStream();

            // create objects for writing and reading across stream
            writer = new BinaryWriter(output);
            reader = new BinaryReader(output);

            string theReply = "";

            do
            {
                try
                {
                    // read the string sent to the server
                    theReply = reader.ReadString();

                    int i = 0;

                    foreach (var x in theReply.Split('#'))
                    {
                        ReadString[i] = x;
                        i++;
                    }

                    CheckConnection(ReadString[0]);



                }
                catch (Exception)
                {
                    //do nothing
                }

            } while (ReadString[6].Equals(" ") &&
                   connection.Connected);

            updatelabel = () => GameResult(ReadString[6]);
            Dispatcher.Invoke(new Action(updatelabel));

            if (!connection.Connected)
            {
                MessageBox.Show("The connection was lost. The game will be closed automatically.");
                writer.Close();
                reader.Close();
                output.Close();
                connection.Close();
                this.Close();
            }

        }
        // handle exception if error in establishing connection
        catch (Exception error)
        {
            MessageBox.Show("Check Internet Connectivity. Couldn't connect!");
        }


    }

when the code enters the method ( check connection ) and calls the dispatcher the app freezes.

     void CheckConnection(string ii)
    {
        try
        {
            if (ii.Equals("Connected"))
            {
                MessageBox.Show("A Connection was established");




                int x = Convert.ToInt32(ReadString[1]);

                if (x == 1)
                {

                    updatelabel = () => char1RadioButton2.IsEnabled = false;
                    char1RadioButton2.Dispatcher.Invoke(new Action(updatelabel));
                }

                else
                {
                    updatelabel = () => char5RadioButton2.IsEnabled = false;
                    char5RadioButton2.Dispatcher.Invoke(new Action(updatelabel));
                }


                updatelabel = () => CreatingGameGrid.Visibility = System.Windows.Visibility.Visible;
                CreatingGameGrid.Dispatcher.Invoke(new Action(updatelabel));



                updatelabel = () => JoinGameGrid.Visibility =        System.Windows.Visibility.Visible;
                JoinGameGrid.Dispatcher.Invoke(new Action(updatelabel));

            }
            else
            {
                MessageBox.Show("No Such Game found");
                this.Close();
            }
        }
        catch (Exception x)
        {
            MessageBox.Show(x.ToString());
        }
    }

解决方案

The Dispatcher.Invoke attempts to synchronously run the specified action on the Dispatcher Thread.

Assuming the RunClient is run on the Dispatcher Thread, and the while loop continues to run while you are trying to Invoke back onto the Dispatcher Thread, the call will freeze.

The simplest solution is to replace all the Dispatcher.Invoke with Dispatcher.BeginInvoke and give it a priority that will run once your RunClient is finished.

The other solution is to run RunClient on a BackgroundWorker.

Similar questions with answers are

  1. Dispatcher.Invoke loop freeze UI
  2. Dispatcher.Invoke hangs main window.

Response to comment on ReadString freeze

Calling Read on a NetworkStream is a blocking call. Well, in fact, it is the Stream obtained by calling TcpClient.GetStream() that blocks. The documentation on MSDN states 'After you have obtained the NetworkStream, call the Write method to send data to the remote host. Call the Read method to receive data arriving from the remote host. Both of these methods block until the specified operation is performed'.

I used dotPeek to see what ReadString was doing and the first thing it does is read the length of the incoming string off the stream using NetworkStream.ReadByte which will block until it has a value to read.

That means the ReadString will sit there until there is data available to read and the amount of data is the same as or more than is expected. You will need to check if you have anything to read before you do by calling stream.DataAvailable or reader.PeekChar.

Alternatively, you could run your socket code on a separate thread. If you are using .Net 4.5, I would take a good look at the Task Parallel Library. ntziolis says in an answer to this question that 'We have made good experiences with that (long being days rather than minutes or hours).'

这篇关于应用程序冻结后Dispatcher.Invoke的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆