我的WPF程序,需要连接PLC、CCD、RFID、扫码枪、控制卡
所以我写了
InitHardware();
private void InitHardware()
{
var tasks = new Task[]
{
//后台线程长连接,不取消令牌
Task.Factory.StartNew(() => InitConnPLC(),CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default),
Task.Factory.StartNew(() => InitConnRFId(),CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default),
Task.Factory.StartNew(() => InitConnCCd(),CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default),
Task.Factory.StartNew(() => InitScanCode(),CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default),
Task.Factory.StartNew(() => InitControlCard(),CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default),
};
Task.Factory.ContinueWhenAll(tasks, completedTasks =>
{
// 当所有任务完成时的逻辑
foreach (var task in completedTasks)
{
if (task.IsFaulted)
{
// 处理任务异常
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
HandyOrgMessageBox.Info("Task。PLC连接失败"); //这段代码先放着,我在其他地方做了异常处理
}));
}
// 其他所有任务完成时的逻辑
}
});
}
/// <summary>
/// 初始化PLC,为了应对不同公司的风格
/// PLC读取Ini文件
/// </summary>
public void InitConnPLC()
{
PlcClient.Current.PlcCount = SysPlc.PlcCount = IniHelper.Current.GetPath("Config/setting.ini").GetSection("PlcCount").ToInt();
PlcClient.Current.DefaultPlc = ObPLC.Where(it => it.IP == IPHelper.LocalIP4FromPLC).First(); //如果一个PLC走这条线,用于前期测试,正式发布可以不写DefaultPlc,会自动跟据PlcCount的多少连接
PlcClient.Current.FindRuningPlc = ObPLC.ToArray(); //如果多个PLC走这条线
while (true)
{
Task.Delay(200);
Dispatcher.CurrentDispatcher.Invoke(
new Action(() =>
{
PlcInfo.IsConn = result.IsSuccess;
PlcInfo.PlcName = PlcInfo.IsConn ? "已连接PLC" : "未连接PLC";
})
);
}
}
可以看出我在这5个类似的方法中频繁更新UI,因为我要和设备长连接
解决方案1、将更新UI从while中剔除出来,写在UI线程
首先增加一个静态的全局变量
public class SysPlc
{
public static bool IsConn {get;set;}
}
那么 Dispatcher.CurrentDispatcher.Invoke不必频繁去写。
修改while
while (true)
{
Task.Delay(200);
var result = PlcClient.Current.ConnectionPLC;
SysPlc.IsConn = result.IsSuccess;
}
然后加入定时器
_dispatcherTimer = new DispatcherTimer();
_dispatcherTimer.Interval = TimeSpan.FromMilliseconds(500);
_dispatcherTimer.Tick += OnTick;
_dispatcherTimer.Start();
在UI线程通过全局静态传递过来的数据更新UI
private void OnTick(object sender, EventArgs e)
{
PlcInfo.PlcName = SysPlc.IsConn ? "已连接PLC" : "未连接PLC";
}
标签:Task,Factory,PLC,UI,WPF,连接,卡顿,IsConn
From: https://www.cnblogs.com/guchen33/p/18263124