异步框架TaskEx.延迟问题

本文关键字:问题 延迟 TaskEx 框架 异步 | 更新日期: 2023-09-27 17:58:11

我在调用TaskEx时发现了一些问题。C#中异步框架CTP的延迟

public async Task<string> TestAsync() {
    return await TaskEx.RunEx<string>( async () => { //in real app this is time consuming code so this line is so complex 
            await TaskEx.Delay( 1000 );
            return "test;
        } );
}
public async void Test {
    var count = 0;
    while( count < 100 ) {
        var val = await TestAsync();
        Console.WriteLine( val ); // in real app this line adds elements to observable collection binded to ListBox
        count++;
    }
}

控制台上的输出大多出现一次(有时两三次),但不像我预期的那样出现100次。

编辑:

它不是控制台应用程序(上面的代码被简化了),而是WP7应用程序。如果不使用Delay,它可以正常工作。

异步框架TaskEx.延迟问题

这是因为方法Test实际上是一个异步方法。C#编译器只允许您通过void返回类型来隐藏这一点。因此,如果你的主要方法看起来像下面的

public static void Main() {
  Test();
}

那么它实际上并没有运行Test并等待它完全完成。相反,它实际上是在调度Test的运行,它的完成将在未来的某个时候发生。因此,看到不同的输出是有道理的,因为它与时间有关。

这可能是因为您在Console应用程序中运行,而不是在Windows应用程序中。

异步在控制台应用程序中的行为与在Windows窗体、WPF或WCF应用程序中不同,因为没有同步上下文。因此,wait会发布回线程池线程,而实际上并没有"等待"执行。

如果您在WPF或Windows窗体应用程序中运行此程序,它将按预期运行。


顺便说一句,你的方法过于复杂。你可以做:

public async Task<string> TestAsync() {
    await TaskEx.Delay( 1000 );
    return "test";
}

这将有效地以与以前的方法相同的方式工作,但开销要小得多(而且要简单得多)。