Cross-thread InvalidOperationException

跨线程异常处理
本文介绍了一种解决Windows组件在不同线程间访问引发的Cross-thread InvalidOperationException的方法。通过使用委托和Invoke方法,确保UI更新总是在创建该组件的主线程中执行。

windows not allowed the component be accessed by the thread which doesn't create it.

it will cause error Cross-thread InvalidOperationException

 

1.

 

public Form1() {
    InitializeComponent();
 
    Control.CheckForIllegalCrossThreadCalls = false;
}

2.
delegate

 

 

 

 public partial class Form1 : Form
 {
        public delegate void delegate_boundTreeView();     // delegate
        public delegate_boundTreeView myDelegateBoundTreeView;

 private System.Timers.Timer timer_refresh = new System.Timers.Timer(60000);  // another thread

 Form1()
 {
  boundTreeView ();  // main thread

  myDelegateBoundTreeView = new delegate_boundTreeView(boundTreeView);
  timer_refresh.Elapsed += new ElapsedEventHandler(timer_refresh_Elapsed);
  timer_refresh.Start();
 }

 public void boundTreeView ()
 {
  // edit your windows component treeview or anything else (textbox, combobox)
 }
 
 
 public void timer_refresh_Elapsed(object sender, ElapsedEventArgs e)    
        {
            try
            {
                this.Invoke(this.myDelegateBoundTreeView);

            }
            catch
            {
                timer_refresh.Stop();
                //timer_refresh.Enabled = false;
            }
        }
}

 

control.invoke

 

http://msdn.microsoft.com/zh-cn/library/zyzhdc6b.aspx

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.invokerequired.aspx

public List<RobotExecuteTask> SelectCanExecuteTasks( List<RobotTask> tasks, StationLockStatus r, StationLockStatus w, bool firstStart) { List<RobotExecuteTask> result = new List<RobotExecuteTask>(); if (tasks == null || tasks.Count == 0) { return result; } BasketInfo basketInfo = StaticsInfo.STATICS_INFO.BasketInfos.FirstOrDefault(b => b.Code == tasks[0].StationStatus.SlotStatus.BasketStatus.StationCode); if (basketInfo == null) { throw new InvalidDataException("can not find basket"); } List<string[]> stationsSeq = basketInfo.StationsSeq; if (RobotHelper.IsEmpty(r, w)) { for (var i = 0; i < stationsSeq.Count - 1; i++) { var current = stationsSeq[i]; var next = stationsSeq[i + 1]; List<RobotTask> currentTasks = tasks.FindAll(t => current.Contains(t.StationStatus.StationCode)); List<RobotTask> nextTasks = tasks.FindAll(t => next.Contains(t.StationStatus.StationCode)); if (currentTasks != null && currentTasks.Count > 0) { Dictionary<string, StationRobotTask> groupTasks = new Dictionary<string, StationRobotTask>(); foreach (var currentTask in currentTasks) { if (!groupTasks.TryGetValue(currentTask.StationStatus.StationCode, out var stationRobotTask)) { stationRobotTask = new StationRobotTask(); groupTasks[currentTask.StationStatus.StationCode] = stationRobotTask; } if (currentTask.PutType == TaskType.Get) { stationRobotTask.GetTasks.Add(currentTask); } if (currentTask.PutType == TaskType.Put) { stationRobotTask.PutTasks.Add(currentTask); } } // 每个工位 foreach (var stationTaskGroup in groupTasks) { StationRobotTask stationRobotTask = stationTaskGroup.Value; //当前工位取 if (stationRobotTask.GetTasks.Count > 0) { var currentGetGetTask = stationRobotTask.GetTasks .OrderBy(a => a.StationStatus.SlotStatus.Priority).FirstOrDefault(); var slotStatusSelectedStationCode = currentGetGetTask.StationStatus.SlotStatus.SelectedStationCode; RobotTask nextGetTask = string.IsNullOrEmpty(slotStatusSelectedStationCode) ? nextTasks.FirstOrDefault(t => t.PutType == TaskType.Get) : nextTasks.FirstOrDefault(t => t.PutType == TaskType.Get && t.StationStatus.StationCode == slotStatusSelectedStationCode); if (nextGetTask != null) { //构造交换预放任务 RobotExecuteTask t = new RobotExecuteTask() { Type = RobotExecuteTaskType.Exchange, RobotState = RobotState.Empty }; Pair currentGet = new Pair(); currentGet.GetTask = currentGetGetTask; t.Tasks.Add(currentGet); SlotStepStatus nextPutSlotStep = currentGet.GetTask.StationStatus.SlotStatus.SlotStepStatues.FirstOrDefault(ss => ss.Stations.Exists(s => s.StationCode == nextGetTask.StationStatus.StationCode)); StationStatus nextStationStatus = nextPutSlotStep.Stations.FirstOrDefault(s => s.StationCode == nextGetTask.StationStatus.StationCode); // 提前锁定工位 nextPutSlotStep.PreviousSlotStepStatus.PreLockStation = nextStationStatus.StationCode; Pair nextGetAndPut = new Pair(); nextGetAndPut.GetTask = nextGetTask; currentGet.GetTask.RobotArm = RobotLockControl.RStation; nextGetTask.RobotArm = RobotLockControl.WStation; nextGetAndPut.PutTask = new RobotTask() { Maked = true, StationStatus = nextStationStatus, FlowStatus = currentGet.GetTask.FlowStatus, RobotStation = nextGetTask.RobotStation, PutType = TaskType.Put, RobotArm = RobotLockControl.RStation, CancellationTokenSource = currentGet.GetTask.CancellationTokenSource, PrePutTask = true }; t.Tasks.Add(nextGetAndPut); return new List<RobotExecuteTask>() { t }; } //工位选片匹配任务 RobotTask nextPutTask = nextTasks.FirstOrDefault(t => t.PutType == TaskType.Put && t.StationStatus.StationCode == currentGetGetTask.StationStatus.SlotStatus.SelectedStationCode); if (nextPutTask != null) { RobotExecuteTask t = new RobotExecuteTask() { Type = RobotExecuteTaskType.CrossGetAndPut, RobotState = RobotState.Empty }; Pair cross = new Pair() { GetTask = currentGetGetTask, PutTask = nextPutTask }; cross.GetTask.RobotArm = cross.PutTask.RobotArm = RobotLockControl.RStation; t.Tasks.Add(cross); t.FromStation = t.Tasks[0].GetTask?.StationStatus?.StationCode; t.ToStation = t.Tasks[0].PutTask?.StationStatus?.StationCode; return new List<RobotExecuteTask>(){t}; } } } } else { if (nextTasks.Count > 0) { RobotTask lastTask = nextTasks.FirstOrDefault(t => t.PutType == TaskType.Get && t.StationStatus.SlotStepStatus.IsLastStep); if (lastTask != null) { lastTask.RobotArm = RobotLockControl.RStation; return new List<RobotExecuteTask>() { new RobotExecuteTask() { FromStation = lastTask.StationStatus.StationCode, ToStation = lastTask.StationStatus.SlotStatus.BasketStatus.StationCode, RobotState = RobotState.Empty, Type = RobotExecuteTaskType.Get, Tasks = { new Pair() { GetTask = lastTask } } } }; } } } } } //因为交换拿起来的 if (RobotHelper.IsOnlyREmpty(r, w)) { if (SelectOneEmpty(tasks, w, out var robotExecuteTasks, RobotLockControl.RStation)) return robotExecuteTasks; } if (RobotHelper.IsOnlyWEmpty(r, w)) { if (SelectOneEmpty(tasks, r, out var robotExecuteTasks, RobotLockControl.WStation)) return robotExecuteTasks; } if (RobotHelper.IsBusy(r, w)) { Log.Error("wrong state"); } if (result.Count == 0 && tasks.Count == 1 && tasks[0].StationStatus.SlotStepStatus.IsLastStep) { Log.Info("can pre move"); } return result; }查明是这个方法里的这个方法if (RobotHelper.IsOnlyWEmpty(r, w)) { if (SelectOneEmpty(tasks, r, out var robotExecuteTasks, RobotLockControl.WStation)) return robotExecuteTasks; },然后这个方法具体是 private static bool SelectOneEmpty(List<RobotTask> tasks, StationLockStatus w, out List<RobotExecuteTask> robotExecuteTasks,string emptyArm) { SlotStatus slot = RobotLockControl.GetRobotStations(RobotLockControl.SwitchArm(emptyArm)).StationStatus?.SlotStatus; if (slot != null) { //后续工位可放 string slotSelectedStationCode = slot.SelectedStationCode; RobotTask slotPutTask = tasks.FirstOrDefault(t => t.StationStatus.StationCode == slotSelectedStationCode && t.PutType == TaskType.Put ); if (slotPutTask != null) { slotPutTask.RobotArm = RobotLockControl.SwitchArm(emptyArm); { robotExecuteTasks = new List<RobotExecuteTask>() { new RobotExecuteTask() { RobotState = RobotState.OnlyREmpty, Type = RobotExecuteTaskType.Put, Tasks = { new Pair() { PutTask = slotPutTask } } } }; return true; } } //后续工位可取 var slotStepStatus = NextSlotStepStatus(slot); if (slotStepStatus != null) { // Log.Info($"{slotStepStatus.StationType}-{slotStepStatus.Stations[0].StationCode}-{slotStepStatus.SlotStatus.Index}"); RobotTask nextGetTask = null; if (String.IsNullOrEmpty(slotSelectedStationCode) || (Global.GetStationState(slotSelectedStationCode) == StationState.Maintenance || Global.GetStationState(slotSelectedStationCode) == StationState.Error)) { nextGetTask = tasks.FirstOrDefault(t => t.PutType == TaskType.Get && slotStepStatus.Stations.Exists(s => s.StationCode == t.StationStatus.StationCode)); } else { nextGetTask = tasks.FirstOrDefault(t => t.PutType == TaskType.Get && slotStepStatus.Stations.Exists(s => s.StationCode == t.StationStatus.StationCode && s.StationCode == slotSelectedStationCode)); } if (!string.IsNullOrEmpty(slot.PrevStationCode) && nextGetTask != null && nextGetTask.StationStatus.StationCode.Substring(0,2) == slot.PrevStationCode.Substring(0,2)) { throw new InvalidOperationException(); } if (nextGetTask != null) { StationStatus stationStatus = slotStepStatus.Stations.FirstOrDefault(s => s.StationCode == nextGetTask.StationStatus.StationCode); RobotExecuteTask t = new RobotExecuteTask() { Type = RobotExecuteTaskType.Exchange, RobotState = RobotState.OnlyREmpty }; nextGetTask.RobotArm = emptyArm; Pair pair = new Pair() { GetTask = nextGetTask, PutTask = new RobotTask() { Maked = true, RobotArm = RobotLockControl.SwitchArm(emptyArm), StationStatus = stationStatus, FlowStatus = nextGetTask.FlowStatus, RobotStation = nextGetTask.RobotStation, PutType = TaskType.Put, CancellationTokenSource = nextGetTask.CancellationTokenSource, PrePutTask = true } }; t.Tasks.Add(pair); t.FromStation = t.Tasks[0].GetTask?.StationStatus?.StationCode; t.ToStation = t.Tasks[0].PutTask?.StationStatus?.StationCode; { robotExecuteTasks = new List<RobotExecuteTask>(){t}; return true; } } } /*if (!string.IsNullOrWhiteSpace(slotSelectedStationCode) && (Global.GetStationState(slotSelectedStationCode) == StationState.Maintenance || Global.GetStationState(slotSelectedStationCode) == StationState.Error)) { Thread.Sleep(300); var currentStep = slot.SlotStepStatues.FirstOrDefault(ss => ss.Stations.Exists(s => s.StationCode == slotSelectedStationCode && s.SlotStatus == slot)); RobotTask otherStationGetTask = tasks.FirstOrDefault(t => currentStep.Stations.Exists(s => s.StationCode == t.StationStatus.StationCode && t.PutType == TaskType.Get)); if (otherStationGetTask != null) { RobotExecuteTask t = new RobotExecuteTask() { Type = RobotExecuteTaskType.Exchange, RobotState = RobotState.OnlyREmpty }; StationStatus stationStatus = currentStep.Stations.FirstOrDefault(s => s.StationCode == otherStationGetTask.StationStatus.StationCode && s.SlotStatus == slot); otherStationGetTask.RobotArm = emptyArm; Pair pair = new Pair() { GetTask = otherStationGetTask, PutTask = new RobotTask() { RobotArm = RobotLockControl.SwitchArm(emptyArm), StationStatus = stationStatus, FlowStatus = otherStationGetTask.FlowStatus, RobotStation = otherStationGetTask.RobotStation, PutType = TaskType.Put, CancellationTokenSource = otherStationGetTask.CancellationTokenSource, PrePutTask = true } }; t.Tasks.Add(pair); slot.SelectedStationCode = otherStationGetTask.StationStatus?.StationCode; t.FromStation = t.Tasks[0].GetTask?.StationStatus?.StationCode; t.ToStation = t.Tasks[0].PutTask?.StationStatus?.StationCode; slot.Status = ExecuteStatusEnum.Prepare; { robotExecuteTasks = new List<RobotExecuteTask>(){t}; return true; } } }*/ } robotExecuteTasks = null; return false; } 最后是这句if (!string.IsNullOrEmpty(slot.PrevStationCode) && nextGetTask != null && nextGetTask.StationStatus.StationCode.Substring(0,2) == slot.PrevStationCode.Substring(0,2)) { throw new InvalidOperationException(); }报错了,怎么解决
最新发布
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值