之前做过一个winform的TCP通讯的程序,只要在load函数加一句CheckForIllegalCrossThreadCalls = false;即可。但是到了wpf里面这句话没了,查阅了很多资料,把我所理解的wpf多线程分享一下
大部分人百度,查出来的都是这么一个答案:
private void ReciveMsg(object o)//接收函数
{
this.Dispatcher.Invoke(new Action(delegate
{
try
{
client = o as Socket;
//创建缓存内存,存储接收的信息 ,不能放到while中,这块内存可以循环利用
byte[] arrlist = new byte[1024 * 1024];
while (true)
{
//TCP接收代码,核心是下面这一句
int length = client.Receive(arrlist);
if (length <= 0)
{
return;
}
string receive = Encoding.UTF8.GetString(arrlist, 0, length);
//TCP接收到的数据放在控件上的代码,因人而异不写了
}
catch (Exception ex)
{
}
}));
}
这种函数如果是秒收到的TCP数据还是可以的,直到我遇到了一个需要等待40s才收到的TCP通讯,client.Receive(arrlist)这句一直卡了40s直到收到数据才能动,一开始想的是设置超时时间,即:
client.SendTimeout = 2000;
client.ReceiveTimeout = 2000;
这样过了2s中还没收到数据程序就不卡死了,但是收不到想要的数据了,并不能解决核心程序假死问题。后来百度了一下午,有点懂得WPF多线程的使用:
WPF其实就只有一个UI主线程,如果代码里要调用UI里面的控件,就要把函数放在:
this.Dispatcher.Invoke(new Action(delegate
{
}));
中即可,如果其他需要等待的函数和UI主线程放一起,就会造成主界面的假死!所以TCP接收的函数,不能和UI线程的函数放一起!
所以换一种思路,先设置一个全局变量在外面,TCP接收的时候赋值给这个变量,然后把UI线程的函数放在一个Timer里面,每隔1ms检测一下是否收到了TCP的数据,下面给一下简单实现的代码:
//自定义全局变量
string receive_TCP_Data = "";
string receive_TCP_Data_Compare = "";
//初始化timer
DispatcherTimer timer = new DispatcherTimer();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//timer
timer.Tick += new EventHandler(timer_Tick);
//设置刷新的间隔时间
timer.Interval = TimeSpan.FromSeconds(0.001);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
this.Dispatcher.Invoke(new Action(delegate
{
try
{
//比较收到的数据是否和之前一样
if (receive_TCP_Data != receive_TCP_Data_Compare )
{
receive_TCP_Data_Compare = receive_TCP_Data;
//下面是控件的具体操作,因人而异
Class_DataGrid_UpdataResult dg = new Class_DataGrid_UpdataResult(
id++,
string.Format("[{0:yyyy-MM-dd HH:mm:ss fff}]", DateTime.Now),
"TCP接收:" + receive_TCP_Data
);
DataGrid_UpdataResult.Items.Add(dg);
DataGrid_UpdataResult.ScrollIntoView(dg);
}
}
catch (Exception ex)
{
}
}));
}
private void ReciveMsg(object o)//接收
{
try
{
client = o as Socket;
//创建缓存内存,存储接收的信息 ,不能放到while中,这块内存可以循环利用
byte[] arrlist = new byte[1024 * 1024];
while (true)
{
int length = client.Receive(arrlist);
if (length <= 0)
{
return;
}
string receive = Encoding.UTF8.GetString(arrlist, 0, length);
//给全局变量赋值
receive_TCP_Data = receive ;
}
}
catch (Exception ex)
{
//MessageBox.Show("ReciveMsg" + ex.Message);
}
}
//TCP建立通讯和发送的就不写了,百度搜搜一堆