[英]Wait for method to be finished C#
I'm communication with an external device (PLC) and he requests data.我正在与外部设备 (PLC) 通信,他请求数据。
I have an event that checks when a value changes in my PLC (for example "NeedNewPosition"
or "NeedNewBarValues"
)我有一个事件可以检查我的 PLC 中的值何时发生变化(例如
"NeedNewPosition"
或"NeedNewBarValues"
)
I would like to change my code that it will handle them one by one.我想更改我的代码,它将一个一个地处理它们。 Sometimes it seems he's handling 2 of them at the same time.
有时他似乎同时在处理其中的两个。 (probably since one takes longer than the other to finish) I've read something about async methods and wait/tasks etc, but that seems a lot of work for something this simple.
(可能因为一个比另一个需要更长的时间才能完成)我已经阅读了一些关于异步方法和等待/任务等的内容,但是对于这么简单的事情来说这似乎需要很多工作。
The code:代码:
private void PLCValueChanged(object sender, EventArgs e)
{
bool xDisplayValue = false;
PLCVar plcvariable = (PLCVar)sender;
string VarName = plcvariable.DisplayName;
switch (VarName)
{
case "NEEDNEWPOSITION": //Writing required position to PLC
if (Convert.ToBoolean(plcvariable.Value))
{
SearchNewPosition();
OPCclient.SendVarToPLC(OPCclient.SendPlcAllBarsFinished, "FALSE");
OPCclient.SendVarToPLC(OPCclient.SendPLCAllMagnetsFinished, "FALSE");
MagnetsInArea = GetMagnetsInWorkArea();
SymbolsInArea = GetSymbolsInWorkArea();
BarsInArea = GetBarsInWorkArea();
}
else
{
OPCclient.SendVarToPLC(OPCclient.SendPLCNewPositionIsSend, "FALSE");
}
break;
case "NEEDNEWBARVALUES": //Writing Bar Values to PLC
if (Convert.ToBoolean(plcvariable.Value))
{
OPCclient.SendVarToPLC(OPCclient.SendPLCBarStrippedOK, "FALSE");
OPCclient.SendVarToPLC(OPCclient.SendPLCBarMagnetsOK, "FALSE");
OPCclient.SendVarToPLC(OPCclient.SendPLCAllBarMagnetsLoose, "FALSE");
SetFirstBarValues();
OffsetsCalculated = false;
StartVisualisation?.Invoke(this, null); //%M59
}
else //if (!Convert.ToBoolean(plcvariable.Value))
{
OPCclient.SendVarToPLC(OPCclient.SendPLCBarDataIsSend, "FALSE");
}
break;
It sounds like you are looking for a Semaphore .听起来您正在寻找Semaphore 。 Like the like/wiki says:
就像喜欢/维基说的:
a semaphore is a variable or abstract data type used to control access to a common resource by multiple threads and avoid critical section problems in a concurrent system such as a multitasking operating system.
信号量是一种变量或抽象数据类型,用于控制多个线程对公共资源的访问,并避免并发系统(如多任务操作系统)中的临界区问题。
Ie you can use the semaphore to "block" until a resource becomes available again.即,您可以使用信号量“阻塞”,直到资源再次可用。
You have multiple types of semaphores in C#, but the simplest to use is the SemaphoreSlim
. C# 中有多种类型的信号量,但最简单的使用是
SemaphoreSlim
。
You can just define a static one for your singleton class instance您可以为您的 singleton class 实例定义一个 static
private static readonly SemaphoreSlim _semaphore = new(1, 1);
The 1,1
means: "1 is available, and there can only be 1". 1,1
表示:“1 可用,并且只能有 1”。
Then in your code:然后在您的代码中:
// take a semaphore, or wait until it is available
await _semaphore.WaitAsync(Timeout.Infinite, cancellationToken);
try
{
[.. your work...]
}
finally
{
// give the semaphore back
_semaphore.Release();
}
Note, I'm using await
here, because this means the thread becomes available for other tasks.注意,我在这里使用
await
,因为这意味着线程可以用于其他任务。 It will also wait indefinitely until a semaphore is available.它还将无限期地等待,直到信号量可用。 The way to stop this is the
cancallationToken
.阻止这种情况的方法是
cancallationToken
。
You could wait for the processing of the first event to be finished using an AutoResetEvent
:您可以使用
AutoResetEvent
等待第一个事件的处理完成:
using System.Threading;
// ...
// declare lock as a static class member
private static AutoResetEvent barsInAreaLoaded = new AutoResetEvent(false);
private void PLCValueChanged(object sender, EventArgs e)
{
// ...
switch (VarName)
{
case "NEEDNEWPOSITION":
if (Convert.ToBoolean(plcvariable.Value))
{
// ...
BarsInArea = GetBarsInWorkArea();
// signal waiting thread that bars are ready
barsInAreaLoaded.Set();
}
// ...
break;
case "NEEDNEWBARVALUES":
if (Convert.ToBoolean(plcvariable.Value))
{
// ...
// block until bars are ready
barsInAreaLoaded.WaitOne();
SetFirstBarValues();
// ...
}
// ...
break;
Note that this will only work if you are sure that the processing of two corresponding NEEDNEWPOSITION
and NEEDNEWBARVALUES
messages overlap.请注意,这仅在您确定两个相应的
NEEDNEWPOSITION
和NEEDNEWBARVALUES
消息的处理重叠时才有效。 If some of those messages actually pile up this won't solve your problem and you should consider implementing some kind of message queue/pipeline.如果其中一些消息实际上堆积起来,这不会解决您的问题,您应该考虑实施某种消息队列/管道。
Not sure if it can solve your question, i am not expert in PLC but about async method is pretty simple to implement.不确定它是否可以解决您的问题,我不是 PLC 专家,但异步方法很容易实现。
I suggest a simple example for the async part.我建议异步部分的一个简单示例。 Of course is not complete and i suggest you to check out the MSDN page anyway:
当然不完整,我建议您还是查看MSDN 页面:
declare the function as: private async void...
将 function 声明为:
private async void...
run an async function like:运行异步 function ,如:
await Task.Run(() =>
{
// code to run async here
});
Statement await
is one you are looking for (probably)!声明
await
是您正在寻找的(可能)!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.