是否可以在异步方法中 return 指向 IAsyncEnumerable 的指针?
Is it possible to return a pointer to an IAsyncEnumerable in an async method?
我有一个处理数据的异步方法reader,它带有传递给它的委托函数。委托的目的是从 reader 构造域对象并将其返回给调用者。我想要一个构造委托和 reader 的中间方法,并且 return 从被调用的方法生成 IAsyncEnumerable。我能够做到这一点的唯一方法是实际使用 IAsyncEnumerable 并从中间方法中产生这些结果。尝试仅 return 直接导致编译器错误,指出我必须使用 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;
}
在这种情况下,您可以将 ProcessReader
更改为接受 Task<MySqlDataReader>
而不是 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
方法更改为 return Task<IAsyncEnumerable<DataObject>>
:
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);
}
我有一个处理数据的异步方法reader,它带有传递给它的委托函数。委托的目的是从 reader 构造域对象并将其返回给调用者。我想要一个构造委托和 reader 的中间方法,并且 return 从被调用的方法生成 IAsyncEnumerable。我能够做到这一点的唯一方法是实际使用 IAsyncEnumerable 并从中间方法中产生这些结果。尝试仅 return 直接导致编译器错误,指出我必须使用 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;
}
在这种情况下,您可以将 ProcessReader
更改为接受 Task<MySqlDataReader>
而不是 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
方法更改为 return Task<IAsyncEnumerable<DataObject>>
:
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);
}