Mot*_*ohn 6 c# sql-server foreach dapper dapper-simplecrud
我有以下代码:
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));
Run Code Online (Sandbox Code Playgroud)
我得到了
InvalidOperationException:连接不支持MultipleActiveResultSets
我不明白我await正在进行每次更新,所以为什么我会收到此错误.
注意:我无法控制连接字符串,因此无法打开MARS.
ven*_*mit 30
您需要MultipleActiveResultSets在连接字符串中添加属性并将其设置为true以允许多个活动结果集.
"Data Source=MSSQL1;" & _
"Initial Catalog=AdventureWorks;Integrated Security=SSPI;" & _
"MultipleActiveResultSets=True"
Run Code Online (Sandbox Code Playgroud)
欲了解更多信息,请访问:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets
Raf*_*eis 11
问题是ForEach方法不是异步方法。它不会等待您的 lambda 返回的任务。运行该代码将触发每个任务,而不是等待其中任何一个完成。
一般要点:将 lambda 标记为异步不会使您传递给它的同步方法以异步方式运行。
解决方案:您将需要使用等待任务完成的 foreach 循环。
例如:foreach (var x in xs) await f(x);
如果您愿意,可以将其包装在辅助方法中。
(我知道这是一个老问题,但我认为没有明确回答)
该代码为列表中的每个项启动一个Task,但不等待每个任务在开始下一个任务之前完成.在每个任务中,它等待更新完成.尝试
Enumerable.Range(1, 10).ToList().ForEach(async i => await Task.Delay(1000).ContinueWith(t => Console.WriteLine(DateTime.Now)));
Run Code Online (Sandbox Code Playgroud)
这相当于
foreach (var i in Enumerable.Range(1, 10).ToList() )
{
var task = Task.Delay(1000).ContinueWith(t => Console.WriteLine(DateTime.Now));
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是非异步方法,则必须等待Wait(),而不是等待每个任务.例如
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
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
所以你的例子会变成
await test.WhenAllOneByOne(conn.UpdateAsync);
Run Code Online (Sandbox Code Playgroud)
我通常调用第二个助手而不是Task.WhenAll,如下所示:
await Task.WhenAll(source.Select(transform)); // not MARS-safe
await source.WhenAllOneByOne(transform); // MARS-safe
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18720 次 |
| 最近记录: |