【发布时间】:2015-06-05 16:41:18
【问题描述】:
我正在构建一个项目并使用 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;
}
【问题讨论】:
-
这里没有固定的最终答案,这完全取决于。我的简短意见;如果一个方法本身不使用任何异步构造,那么它本身不应该是异步的,只是为了适应某些方法。
-
只是一个小提示。我喜欢使用调用堆栈和相关工具进行调试,我会因此而讨厌你。 Async/Await 是相当复杂的实际代码的简单语法,在某些时候可能会咬你。
-
您误解了“一路异步”的概念——它是关于让您的整个异步 调用层次结构 异步。也就是说,如果你调用一个异步方法,你自己应该是异步的,你的调用者和他的调用者等也应该是异步的。但是没有理由编写
string.JoinAsync或类似的东西 - 事实上,它会适得其反。如果你只调用同步方法,你不应该是异步的——那只是误导。
标签: c# asp.net .net asynchronous async-await