在C#中是否有`when()`语句或一些等价物?

时间:2018-05-12 09:18:30

标签: c# .net

是否有类似"何时" C#中的陈述?

我之所以这样做是因为if语句只会在特定时间检查某个属性是true,但我希望等待直到属性是true

任何人都知道我在C#中可以做的事情类似于"当"声明?

5 个答案:

答案 0 :(得分:6)

你想要的是SpinWait

e.g。 REM some code.......

它将坐在那里,直到它超时(使用您指定的超时)或满足条件。

答案 1 :(得分:4)

没有when控制语句,但有两个选项可以满足您的需求:

您可以使用while(predicate){}循环来保持循环,直到满足条件。谓词可以是任何返回true / false的表达式 - 只要条件为真,它就会循环。如果你只是想在没有消耗太多CPU的情况下等待,你可以在循环中Sleep()线程:

while(name == "Sebastian")
{
    // Code to execute
    System.Threading.Thread.Sleep(1000);
}

如果您的属性是数字范围,则可以使用for循环,但这听起来并不像您想要的那样。

答案 2 :(得分:2)

如果你想处理异步世界,你应该看看库Rx.NET。让我们看一个简单的例子:假设你想要从控制台读取字符串,用户输入单词"hello"时需要在响应中打印"world"。这个简单的例子可以实现如下:

var inputLines = new Subject<string>();
inputLines.Subscribe(info =>
{
    if (info == "hello")
        Console.Out.WriteLine("world");
});
while (true)
{
    var line = Console.In.ReadLine();
    inputLines.OnNext(line);
}

因此,有明确的时间操作,我们传递了Subscribe(...)函数。

在这个简单的例子中,Rx.NET的使用显然是不必要的,你不应该这样做。但在更复杂的场景中,这是一个非常有用的库。您可以看到,使用Reactive Extensions,您可以从主事件池中分离应用程序的逻辑,您可以在其中执行其他与应用程序逻辑无关的工作。此外,您可以通过此库获得高度灵活性,因为它非常动态 - 您可以随时在运行时订阅和取消订阅不同的事件。

您可以注意到,在基于事件的范例中,还有另一种方法可以解决我的示例。我们可以简单地使用这样的内置事件:

public static event EventHandler<string> InputEvent;
public void Run() 
{
    InputEvent += (sender, line) =>  {
        if (line == "hello")
            Console.WriteLine("world");
    };

    while (true) {
        var line = Console.In.ReadLine();
        InputEvent?.Invoke(this, line);
    }
}

这是一个正确的观点,有时你可以用简单的事件替换Reactive Extensions,因为它们是连接的。但是当您需要从许多事件源构建复杂管道并使用许多不同的紧密耦合操作时,Reactive Extensions允许您以非常声明的方式很好地构建此管道。

答案 3 :(得分:0)

您可以使用'async'和'await'来等待某个'任务'完成。 'await'有点类似于你需要的'when'语句。只有它暂停当前的“任务”,直到等待的“任务”完成任何结果,而不仅仅是当表达式变为“真”时。另请参阅TaskCompletionSource

答案 4 :(得分:0)

你想在这里实现什么?您是在运行同步进程还是在等待异步发生?

如果你是同步那么while可能是正确的解决方案:

var result = 0;
while(result != 6)
{
    result = RollADie();
    Console.WriteLine($"I rolled a {result}");
}
Console.WriteLine("At last, a six!");

但是 - 如果您正在等待发生异步的事情,则需要调用其他解决方案。异步场景是您希望代码在等待,无所事事的地方。直到条件满足。

在这种情况下,现代C#解决方案是使用asyncawait关键字的异步编程,以及Task类(以及它的通用表兄{{1} })。这可能有点深入,但是here's a pretty good primer

重要的是,您没有使用基于Task<TResult> 的解决方案来处理异步流程。你只是让CPU旋转圈,追逐它自己的尾巴可以说,当你真的想说'#34;现在停止工作直到X发生&#34;。另外,出于相关原因,请避免基于whilewhile的任何解决方案。