Kev*_* k5 5 c# sockets wpf multithreading
我有这个应用程序在调用dispatcher.invoke进行任何控制时冻结.
当我在radiobutton,Grid,Image ..etc中调用Dispatcher时,应用程序会冻结,但不会出错.任何帮助请!!! 谢谢
我调用线程方法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!");
}
}
Run Code Online (Sandbox Code Playgroud)
当代码进入方法(检查连接)并调用调度程序时,应用程序冻结.
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());
}
}
Run Code Online (Sandbox Code Playgroud)
该Dispatcher.Invoke试图同步运行的调度程序线程指定的操作.
假设RunClient在Dispatcher Thread上运行,并且while循环在您尝试重新调用Dispatcher Thread时继续运行,则调用将冻结.
最简单的解决方案是使用Dispatcher.BeginInvoke替换所有Dispatcher.Invoke,并为其设置一个优先级,该优先级将在RunClient完成后运行.
另一种解决方案是在运行RunClient BackgroundWorker的.
有答案的类似问题是
回应对ReadString冻结的评论
在NetworkStream上调用Read是一个阻塞调用.嗯,实际上,它是通过调用阻塞的TcpClient.GetStream()获得的Stream .MSDN上的文档说明' 获得NetworkStream后,调用Write方法将数据发送到远程主机.调用Read方法以接收从远程主机到达的数据.这两种方法都会阻塞,直到执行指定的操作为止.
我使用dotPeek来查看ReadString正在做什么,它首先要做的是使用NetworkStream.ReadByte从流中读取传入字符串的长度,它将阻塞直到它有一个要读取的值.
这意味着ReadString将一直存在,直到有可读数据,数据量与预期相同或更多.您将需要检查,如果您有任何你通过调用之前做阅读stream.DataAvailable或reader.PeekChar.
或者,您可以在单独的线程上运行套接字代码.如果你使用.Net 4.5,我会好好看看任务并行库.ntziolis在回答这个问题时说," 我们已经取得了很好的经验(长期是几天而不是几分钟或几小时)."
归档时间: |
|
查看次数: |
7450 次 |
最近记录: |