繁体   English   中英

等待任务不适用于IEnumerable

[英]await Task doesn't work with IEnumerable

我正在尝试异步执行现有的同步方法,但是,如果该方法是IEnumerable ,那么它似乎会跳过该方法。

这是我要实现的目标的简化版本。

public partial class MainWindow : Window
{
    private IEnumerable<int> _Result;

    public MainWindow()
    {
        InitializeComponent();

        DoSomethingAmazing();
    }

    private async void DoSomethingAmazing()
    {
        _Result = await DoSomethingAsync();
    }

    private IEnumerable<int> DoSomething()
    {
        Debug.WriteLine("Doing something.");

        //Do something crazy and yield return something useful.
        yield return 10;
    }

    private async Task<IEnumerable<int>> DoSomethingAsync()
    {
        //Perform the DoSomething method asynchronously.
        return await Task.Run(() => DoSomething());
    }
}

本质上,创建MainWindow时,它将触发异步方法来填充_Result字段。

现在, DoSomething从未真正执行过。 调试消息永远不会出现。

如果我将IEnumerable更改为List ,那么一切都很好。 该方法被执行,结果被填充。

我想使用IEnumerable主要原因是因为我想利用yield return ,它并不是完全必要,但主要只是一个首选项。 我遇到了这个问题,从那以后我一直在挠头。

运行DoSomething方法的结果是一个实现IEnumerable<int>的类,并在枚举它时运行您的代码。 您的问题与使用异步无关。 如果运行以下代码

var result = DoSomething();
Debug.WriteLine("After running DoSomething");
var resultAsList = result.ToList();
Debug.WriteLine("After enumerating result");

您将获得此输出。

运行DoSomething之后

做某事。

枚举结果后

现在,DoSomething从未真正执行过。 调试消息永远不会出现。

这是因为当您使用yield return ,编译器将生成一个为您实现IEnumerable<T>的类,并返回迭代器。 看起来像这样:

Program.<DoSomething>d__3 expr_07 = new Program.<DoSomething>d__3(-2);
expr_07.<>4__this = this;
return expr_07;

其中<DoSomething>d__3是编译器生成的类,实现IEnumerable<int>

现在,由于迭代器使用了延迟执行,因此除非您明确地进行了迭代,否则它不会开始执行。

如果我将IEnumerable更改为List,那么一切都很好。 该方法被执行,结果被填充。

这是因为当您使用List ,您正在实现迭代器,从而有效地使其执行。 这就是为什么您会看到调试消息的原因。

更改您的DoSomethingAmazing方法,它将起作用。

    private async void DoSomethingAmazing()
    {
        _Result = await DoSomethingAsync();
        foreach (var item in _Result)
        {
            Debug.WriteLine(item);
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM