我有一个类,它具有一个名为ActiveDelay
的属性,该类用于定义一个持续时间,在该持续时间内,条件评估应等待之后再检查条件是否仍然为真。属性SetpointA
是用于将给定值与之进行比较的值。
下面是我目前正在做的事情
public void EvaluateCondition(T value)
{
if(value.Equals(SetpointA))
{
Task.Delay(ActiveDelay).ContinueWith(_ => EvaluateConditionDelayed(GetValue())).Wait();
}
}
private void EvaluateConditionDelayed(object value)
{
if (value.Equals(SetpointA))
{
Console.WriteLine("Waited and worked");
}
else
{
Console.WriteLine("Condition now false");
}
}
我两次调用函数EvaluateCondition
,一次的TimeSpan为5秒,另一次的TimeSpan为2秒,我希望2秒调用应该在5秒调用之前完成,但是实际上会发生什么是5秒钟的电话等待,然后2秒钟的电话等待。
我认为与异步有关,并且在这里等待,但是我没有找到对我有帮助的信息。
我想说的很清楚,这些延迟不应该暂停程序,它们应该只在外部等待,并允许程序的其余部分不受影响地运行。
扩展代码部分
此处是上述内容的详尽版本
public class AlarmCondition
{
#region Property declaration
public TimeSpan ActiveDelay { get; set; } // Need to be historised ?
public TimeSpan ClearDelay { get; set; } // Need to be historised ?
#endregion
#region Constructor
public AlarmCondition() { }
public AlarmCondition(TimeSpan activeDelay, TimeSpan clearDelay)
{
ActiveDelay = activeDelay;
ClearDelay = clearDelay;
}
#endregion
}
public class EqualCondition<T> : AlarmCondition
{
#region Property declaration
public T SetpointA { get; }
#endregion
#region Constructor
public EqualCondition() { }
public EqualCondition(TimeSpan activeDelay, TimeSpan clearDelay) : base(activeDelay, clearDelay)
{
SetpointA = setpointA;
}
#endregion
public void EvaluateCondition(T value)
{
if(value.Equals(SetpointA))
{
Task.Delay(ActiveDelay).ContinueWith(_ => EvaluateConditionDelayed(value));
}
}
private void EvaluateConditionDelayed(T value)
{
if (value.Equals(SetpointA))
{
Console.WriteLine("Waited and worked");
}
else
{
Console.WriteLine("Condition now false");
}
}
}
// In another file and namespace
public class ConsoleDisplay
{
public static void Main(string[] args)
{
EqualCondition<bool> condition1 = new EqualCondition<bool>(new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5));
EqualCondition<bool> condition2 = new EqualCondition<bool>(new TimeSpan(0, 0, 2), new TimeSpan(0, 0, 5));
condition1.EvaluateCondition(true);
condition2.EvaluateCondition(true);
}
}
答案 0 :(得分:1)
您可以从您的方法中返回Task
,以便调用者决定是否要等待结果。例如:
public async Task EvaluateCondition(T value)
{
if(value.Equals(SetpointA))
{
await Task.Delay(ActiveDelay);
EvaluateConditionDelayed(GetValue());
}
}
或者,如果您不希望呼叫者拥有做出此类决定的选项,则只需从当前的实现中删除.Wait()
(阻止)即可。即使没有该任务,该任务仍应在控制台中打印(如果您的程序运行时间足够长):
public void EvaluateCondition(T value)
{
if(value.Equals(SetpointA))
{
Task.Delay(ActiveDelay).ContinueWith(_ => EvaluateConditionDelayed(GetValue()));
}
}
UPD
要启动多个EvaluateCondition
并等待它们并行完成,可以使用Task.WhenAll
:
var ev1Task = EvaluateCondition(someVal1);
var ev2Task = EvaluateCondition(someVal2);
await Task.WhenAll(ev1Task, ev2Task);
如果您不想等待,只需跳过await Task.WhenAll(ev1Task, ev2Task)
(并修复警告)。