【问题标题】:Is it possible to return a pointer to an IAsyncEnumerable in an async method?是否可以在异步方法中返回指向 IAsyncEnumerable 的指针?
【发布时间】:2020-10-04 04:43:43
【问题描述】:

我有一个异步方法,它使用传递给它的委托函数来处理数据读取器。委托的目的是从阅读器中构造域对象并将其返回给调用者。我想要一个构造委托和读取器的中间方法,并从被调用的方法返回结果 IAsyncEnumerable。我能够做到这一点的唯一方法是实际使用 IAsyncEnumerable 并从中间方法产生这些结果。尝试直接返回会导致编译器错误,指出我必须使用 yield return 或 yield break。

delegate T ProcessFunc<T>(MySqlDataReader reader);

async IAsyncEnumerable<T> ProcessReader<T>(MySqlDataReader reader, ProcessFunc<T> transformFunc)
{
    while (await reader.ReadAsync() != false)
    {
        yield return transformFunc(reader);
    }

    await reader.DisposeAsync();
}

public async IAsyncEnumerable<DataObject> GetDataObjectsAsync()
{
    ProcessFunc<DataObject> processFunc = (reader) =>
    {
        var id = reader.GetGuid( "id" );

        return new DataObject(id);
    };

    var reader = await GetDataObjectsReaderAsync(); //Constructs appropriate sqlcommand and returns a mysqldatareader

    //only way i can get this to function
    //would like to just be able to write: return ProcessReader(reader, processFunc)
    //so as not to chain another enumerable
    await foreach (var obj in ProcessReader( reader, processFunc ))
        yield return obj; 
}

【问题讨论】:

标签: c# iasyncenumerable


【解决方案1】:

在这种情况下,您可以将您的ProcessReader 更改为接受Task&lt;MySqlDataReader&gt; 而不是MySqlDataReader,这样您就可以使您的GetDataObjectsAsync 同步:

async IAsyncEnumerable<T> ProcessReader<T>(Task<MySqlDataReader> readerTask, ProcessFunc<T> transformFunc)
{
    var reader = await readerTask;
    while (await reader.ReadAsync() != false)
    {
        yield return transformFunc(reader);
    }

    await reader.DisposeAsync();
}

public IAsyncEnumerable<DataObject> GetDataObjects()
{
    ProcessFunc<DataObject> processFunc = (reader) =>
    {
        var id = reader.GetGuid( "id" );

        return new DataObject(id);
    };

    return ProcessReader(GetDataObjectsReaderAsync(), processFunc)
}

或者更改您的GetDataObjectsAsync 方法以返回Task&lt;IAsyncEnumerable&lt;DataObject&gt;&gt;

public async Task<IAsyncEnumerable<DataObject>> GetDataObjectsAsync()
{
    ProcessFunc<DataObject> processFunc = (reader) =>
    {
        var id = reader.GetGuid( "id" );

        return new DataObject(id);
    };

    var reader = await GetDataObjectsReaderAsync(); //Constructs appropriate sqlcommand and returns a mysqldatareader

    return ProcessReader(reader, processFunc); 
}

【讨论】:

  • 这仅仅是签名为异步 IAsyncEnumerable 的函数吗?
  • @cubesnyc 如果我正确理解了您的问题 - 是的,这是因为您的方法被贴花返回 IAsyncEnumerable&lt;T&gt; 并标记为 async
猜你喜欢
  • 2020-04-28
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-17
  • 2010-11-04
相关资源
最近更新 更多