我有以下代码:
var test = new FallEnvironmentalCondition[] {
new FallEnvironmentalCondition {Id=40,FallId=3,EnvironmentalConditionId=1},
new FallEnvironmentalCondition {Id=41,FallId=3,EnvironmentalConditionId=2},
new FallEnvironmentalCondition {Id=42,FallId=3,EnvironmentalConditionId=3}
};
test.ToList().ForEach(async x => await conn.UpdateAsync(x));
我正在接受
InvalidOperationException:连接不支持 MultipleActiveResultSets
我不明白我是await
每次更新,所以为什么我会收到此错误。
注意:我无法控制连接字符串,因此无法启用MARS。
答案 0 :(得分:26)
您需要在连接字符串中添加属性MultipleActiveResultSets
并将其设置为true以允许多个活动结果集。
"Data Source=MSSQL1;" & _
"Initial Catalog=AdventureWorks;Integrated Security=SSPI;" & _
"MultipleActiveResultSets=True"
答案 1 :(得分:6)
该代码为列表中的每个项启动一个Task,但不等待每个任务在开始下一个任务之前完成。在每个任务中,它等待更新完成。尝试
Enumerable.Range(1, 10).ToList().ForEach(async i => await Task.Delay(1000).ContinueWith(t => Console.WriteLine(DateTime.Now)));
相当于
foreach (var i in Enumerable.Range(1, 10).ToList() )
{
var task = Task.Delay(1000).ContinueWith(t => Console.WriteLine(DateTime.Now));
}
如果您使用的是非异步方法,则必须等待Wait(),而不是等待每项任务。 EG
foreach (var i in Enumerable.Range(1, 10).ToList() )
{
var task = Task.Delay(1000).ContinueWith(t => Console.WriteLine(DateTime.Now));
//possibly do other stuff on this thread
task.Wait(); //wait for this task to complete
}
答案 2 :(得分:2)
MARS有一些局限性,而且开销也非零。您可以使用以下帮助程序来使更新顺序进行:
public static async Task WhenAllOneByOne<T>(this IEnumerable<T> source, Func<T, Task> process)
{
foreach (var item in source)
await process(item);
}
public static async Task<List<U>> WhenAllOneByOne<T, U>(this IEnumerable<T> source, Func<T, Task<U>> transform)
{
var results = new List<U>();
foreach (var item in source)
results.Add(await transform(item));
return results;
// I would use yield return but unfortunately it is not supported in async methods
}
因此您的示例将变成
await test.WhenAllOneByOne(conn.UpdateAsync);
我通常叫第二个助手而不是Task.WhenAll
,如下:
await Task.WhenAll(source.Select(transform)); // not MARS-safe
await source.WhenAllOneByOne(transform); // MARS-safe