我浏览了StackOverflow上的其他问题,但其他问题/答案似乎都不符合我的情况:
我在一个类中编写了一个async
方法,我需要从另一个类中的重写方法调用该方法,该方法派生自.NET System.Management.Automation.Cmdlet
类。
我通常会这样调用我的方法:
public async Task TestReadingFile()
{
using MyReader reader = new MyReader(SetupMyStream("Contoso.txt"));
await foreach (MyDataObject obj in reader.GetFrames())
{
Debug.Print($"{reader.Progress}: {obj.GetType().Name} - {obj}");
}
}
现在,在我的类的Cmdlet
基类的ProcessRecord
覆盖中,我不能使用async
。
我该怎么做?
我的期望是使用这样的东西:
protected override void ProcessRecord()
{
using MyReader reader = new MyReader(MyFilePath);
IAsyncEnumerator<MyDataObject> enumerator = reader.GetFrames().GetAsyncEnumerator();
while (enumerator.MoveNextAsync().GetAwaiter().GetResult())
{
MyDataObject obj = enumerator.Current;
Debug.Print($"{reader.Progress}: {obj.GetType().Name} - {obj}");
}
}
但是这种方法抛出了一个InvalidOperationException
。
怎么做才是正确的?
1条答案
按热度按时间pxy2qtax1#
得到
InvalidOperationException
的原因是ValueTask
不能像Task
那样被同步等待,所以简单的解决方法是用AsTask()
方法把它变成Task
。枚举器是一次性的,这意味着你应该在使用后处理它们。而
IEnumerator
继承了IDisposable
,IAsyncEnumerator
继承了IAsyncDisposable
。在正常情况下,你应该使用await using
,但由于方法是同步的,我们必须自己降低这个东西。首先,将其转换为try-finally
结构,然后同步等待返回的任务。