<分区>
我正在构建一个项目并使用 async 和 await 方法。每个人都说异步应用程序是从头开始构建的,那么你真的应该有任何同步方法吗?您是否应该将所有方法都返回一个 Task,以便您可以异步使用?
让我们举一个简单的例子,我使用 Sql 将数据加载到集合中,这里是一些代码。
此代码使用 ExecuteQueryAsync
方法从表中加载数据,方法 GetQuery
构造 SQL,但调用 GetTableColumns
。生成并执行 SQL 后,我循环遍历集合并通过调用 GetDataFromReader
填充每个对象。
我的非异步方法应该是异步的吗?我是不是考虑了太多的同步编程方式而遗漏了什么?
public async Task<ICollection<MyObject>> ExecuteQueryAsync(Module module, List<SqlParameter> parameters)
{
var result = new Collection<MyObject>();
var query = GetQuery(module);
using (var conn = new SqlConnection(_context.Database.Connection.ConnectionString))
{
await conn.OpenAsync();
using (var cmd = new SqlCommand(query, conn))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters.ToArray());
using (var dr = await cmd.ExecuteReaderAsync())
{
while (await dr.ReadAsync())
{
result.Add(GetDataFromReader(module, dr));
}
}
}
}
return result;
}
public string GetQuery(Module module)
{
return "SELECT " + string.Join(",", GetTableColumns(module).ToArray()) + " FROM [TableA] ";
}
public List<string> GetTableColumns(Module module)
{
var columnNames = new List<string>();
// get all list fields for the module
var fields = (from a in module.Groups.SelectMany(a => a.Fields) select a).ToList();
foreach (var field in fields)
{
if (field.Type == FieldType.List) {
string query = "STUFF(";
query += "(SELECT ';' + [Value] FROM [TableB] FOR XML PATH(''))";
query += ", 1, 1, '') AS [" + field.ColumnName + "]";
columnNames.Add(query);
} else {
columnNames.Add("[" + field.ColumnName + "]");
}
}
return columnNames;
}
public MyObject GetDataFromReader(Module module, IDataReader dataReader)
{
var entity = new MyObject();
for (var i = 0; i < dataReader.FieldCount; i++)
{
object value = null;
var fieldName = dataReader.GetName(i);
if (!dataReader.IsDBNull(i))
{
value = dataReader.GetValue(i);
}
entity[fieldName] = value;
}
return entity;
}