在我的(控制台)应用程序中,我有一个任务(levelATask),它启动其他任务(levelBTasks),而它们本身也启动其他任务(levelCTasks)。
有时,我的控制台应用程序运行良好,并显示了应有的一切,但有时它仅执行levelATask,而其中没有任何任务。
这是我的示例:
我有R_Machine.ExecuteSkill(S_Machine_Start);
,R_Machine是Resource
类。资源的类别为List
的Skill
。技能具有方法Execute
,该方法将ExecuteMethod
包装在任务中。 ExectueMethod是技能public Action ExecuteMethod { get; set; }
在技巧上:
private Task executingTask;
/// <summary>
/// Stuff that is exectued when the Skill is active
/// </summary>
/// <param name="o"></param>
public virtual void Execute(object o = null)
{
// if the executing task is not null and didnt already execute to completion
if (executingTask == null || executingTask.IsCompleted)
{
// create the Task
Task t = new Task(() =>
{
if (CanExecute())
{
Logger.Debug($"Executing {Name} of {ExecutingResource.Name}");
SetActive();
ExecuteMethod();
SetFinished();
Logger.Debug($"Finished Executing {Name} of {ExecutingResource.Name}");
if (!string.IsNullOrEmpty(FinishedStation))
{
Logger.Log(FinishedStation);
}
}
});
// set it to the task created previously
executingTask = t;
}
if (NeedsToExecute())
{
// if the task is not running or waiting for it
if (executingTask.Status != TaskStatus.Running &&
executingTask.Status != TaskStatus.WaitingToRun &&
executingTask.Status != TaskStatus.RanToCompletion)
{ // run the task
executingTask.Start();
}
}
}
资源中:
public List<Skill> Skills { get; set; }
public void ExecuteSkill(Skill s, object execParams = null)
{
if (!Skills.Contains(s))
{
Logger.Log($"Could not execute Skill {s.Name}, since it was not in list");
}
else
{
s.Execute(execParams);
}
}
在程序中:
S_Machine_Start.ExecuteMethod = new Action(() =>
{
Console.WriteLine("Machine Starts");
R_St00.ExecuteSkill(S_St00_Start);
R_St01.ExecuteSkill(S_St01_Start);
R_St02.ExecuteSkill(S_St02_Start);
R_St03.ExecuteSkill(S_St03_Start);
R_St04.ExecuteSkill(S_St04_Start);
R_St05.ExecuteSkill(S_St05_Start);
R_St06.ExecuteSkill(S_St06_Start);
});
// similar for other stations
S_St00_Start.ExecuteMethod = new Action(() =>
{
Console.WriteLine("Starting Station 0");
//create time with callback
Timer t = new Timer(new TimerCallback((state) => {
if (!pause)
{
R_St00_BowlFeeder.ExecuteSkill(S_St00_TransportB);
R_St00_RotaryTable.ExecuteSkill(S_St00_Rotate);
R_St00_Seperator.ExecuteSkill(S_St00_GoBack);
R_St00_Seperator.ExecuteSkill(S_St00_Seperate);
}
}));
// start timer with tick interval of 10ms
t.Change(0, 10);
});
R_Machine.ExecuteSkill(S_Machine_Start);
有时控制台显示:
但是有时控制台仅显示:
我还写了一些行到调试窗口。当一切正常时,它显示:
[15:13:14.796] Executing Machine Start
[15:13:14.889] Finished Executing Machine Start
[15:13:14.936] Executing St00 Start of St00
[15:13:14.969] Executing St06 Start of St06
[15:13:14.997] Finished Executing St00 Start of St00
[15:13:15.047] Executing St00 BowlFeeder Transport of St00 Conveyor
[15:13:14.997] Finished Executing St06 Start of St06
[15:13:15.051] Executing of St05
[15:13:15.052] Finished Executing of St05
[15:13:15.053] Executing of St04
[15:13:15.054] Finished Executing of St04
[15:13:15.055] Executing of St03
[15:13:15.056] Finished Executing of St03
[15:13:15.057] Executing St02 Start of St02
[15:13:15.058] Finished Executing St02 Start of St02
[15:13:15.059] Executing St01 Start of St01
[15:13:15.061] Finished Executing St01 Start of St01
[如果它不起作用,它只会显示:
[15:18:34.596] Executing Machine Start
[15:18:34.688] Finished Executing Machine Start
我在Windows 7 VM上运行VS 2017 Professional。有时它起作用,有时却不起作用。一位同事在Windows 10(不是虚拟机)上具有VS 2017和2019社区版,并且永远无法使用。
有人可以告诉我为什么会发生这种纠结,以及我如何使其始终正常工作(执行其他任务中的所有任务)?
谢谢
编辑:完整的代码可以在这里找到:https://www.dropbox.com/sh/qwqdh0y66iuph0u/AACJo50EQLYtX6R9iljgAJyWa?dl=0
我想达到的目标:这基本上是对一台机器的PLC的模拟。一个合作伙伴利用资源和技能为机器创建了一个模型。为了验证该模型是否可行,我使用该模型为真实计算机的plc程序序列编写了该程序仿真。
问题是比赛条件。站中的站仅被调用一次。对于某些工作站,CanExecute方法返回false,因为计算机尚未设置其运行标志。
所以我像S_St00_Start.ExecuteMethod那样实现了一个计时器。另一个解决方案是@spender建议的队列。