首先把文件源码放出来
文件源码
如下是代码,这里面有两个线程,里面各有一个死循环,第一个线程是用来循环保持连接,第二循环是监听任务并执行任务,运行后的结果是,有时候点击会出现未响应,然后过个几秒恢复,我考虑过是Thread.sleep的原因,于是我用Delay()替代了sleep,但是好像没有什么作用,所以请各位帮忙看看
public static void Delay(int mm)
{
DateTime current = DateTime.Now;
while (current.AddMilliseconds(mm) > DateTime.Now)
{
Application.DoEvents();
}
return;
}
//创建一个任务,循环保持连接
Thread stock = new Thread(KeepStockStatus);
stock.Start();
//开始运行
Thread thread = new Thread(new ThreadStart(() =>
{
while (IsRunning)
{
Delay(1000);
//Thread.Sleep(TimeSpan.FromSeconds(1)); //等待1秒钟
int x=monitorStatus();
if (x == STATUS_WORK)
{
//Thread.Sleep(120);
//KeepStockStatus();
Delay(200);
//Thread.Sleep(200);
InRequest();
Delay(100);
//Thread.Sleep(100);
OutRequest();
}
}
}));
thread.IsBackground = true;
thread.Start();
private void InRequest()
{
System.String[] arrData; //Array for 'Data'
//lock (Request_lock)
//{
ShowCurrInStatus("监听是否有入库任务");
try
{
if (Device_Status == 0) //如果马垛车是空闲状态是则询问是否有入库请求
{
Device_Status = 1;
short[] arrDeviceValue = new short[1];
int iReturnCode = axActUtlType1.ReadDeviceRandom2(M10000,
1,
out arrDeviceValue[0]);
if (iReturnCode == 0)
{
arrData = new System.String[1];
for (int i = 0; i < 1; i++)
{
arrData[0] = arrDeviceValue[0].ToString();
}
//收到入库请求
if (arrData[0] == "1")
{
ShowCurrInStatus("有入库任务");
UpdateStockStatus(0);
InitStatus();
//读取货位状态(满/空)
GetPositionList();
ShowCurrInStatus("获取货位列表");
//调用后续任务入库操作
InStockAction();
//修改状态
UpdateStockStatus(1);
ShowCurrInStatus("入库任务执行完毕");
}
}
Device_Status = 0;
}
}catch(Exception ex)
{
WriteLogToFile("InRequest请问出错:"+ex.Message);
}
Delay(1000);
//System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
//}
}
首先在线程里面调用Thread.Sleep()方法是没有任何问题的,并不会造成UI线程的未响应,所以你这个Delay()方法大可以去掉,其次看了你的源代码,感觉问题应该不是出现在上位机这一层,axActUtlType1应该是别人给你的ocx或者activex控件吧?建议你写个测试程序直接调用这个控件的接口,很简单的调用,就是打开,发送请求等等,看看是不是界面也会未响应,因为不管ocx还是activex这种UI控件本身就需要寄宿在上位机的Form上,如果写这个ocx的人没有把很耗时的操作放到新的线程里面去执行那必然会卡你上位机的界面,比如发送或者读取数据和串口等交互的时候是很耗时的,个人感觉问题应该是出在了这个控件上。如果是出现在了这个控件上,那你上位机在怎么折腾也是瞎忙活,解决办法有两个:1.找给你控件的人改代码,让他把耗时的操作自己创建线程去执行,然后给你回掉函数。2.如果实在没办法改这个控件,那就只能你自己写两个程序,一个去调用这个控件,一个来画界面,用进程间通信的方法或者是socket协议都可以。最后,从你调用这个控件的方式来看,都是直接axActUtlType1.方法(),这种同步的调用方式八成是写控件的人直接就在UI线程处理那些接口的逻辑了,根本没考虑卡界面的问题,一般如果考虑的话肯定会给你异步的调用方法,然后通过回调函数把结果给你。
InRequest();
OutRequest();
分别怎么写的,日志输出下,看看是否存在死锁。
看了你的代码文件,Delay()就是错的,while循环条件一直为真,这样UI界面主线程一直在 跑。
如果需要等待工作线程是否完成,应该在界面主线程设置一个定时器,每隔500ms检查一次线程是否工作完成。
或者定义一个全局变量,线程完成任务后更新这个全局变量的状态,这样主线程可以定时获取这个全局变量的状态值,
就自然知道子线程的完成情况了.
把主函数上的[STAThread]去掉,有可能能改善,当然也可能导致程序崩溃,你可以试试