我有以下代码:
innerExceptions = dbconnByServer
.AsParallel()
.WithDegreeOfParallelism(dbconnByServer.Count)
// A stream of groups of server connections proceeding in parallel per server
.Select(dbconns => dbconns.Select(dbconn => m_sqlUtilProvider.Get(dbconn)))
// A stream of groups of SqlUtil objects proceeding in parallel per server
.Select(sqlUtils => GetTaskException(sqlUtils
// Aggregate SqlUtil objects to form a single Task which runs the SQL asynchronously for the first SqlUtil, then upon completion
// for the next SqlUtil and so long until all the SqlUtil objects are processed asynchronously one after another.
.Aggregate<ISqlUtil, Task>(null, (res, sqlUtil) =>
{
if (res == null)
{
return sqlUtil.ExecuteSqlAsync(SQL, parameters);
}
return res.ContinueWith(_ => sqlUtil.ExecuteSqlAsync(SQL, parameters)).Unwrap();
})))
.Where(e => e != null)
.ToList();
在哪里:
private static Exception GetTaskException(Task t)
{
try
{
t.Wait();
return null;
}
catch (Exception exc)
{
return exc;
}
}
这段代码所做的是跨多个数据库连接执行某些 SQL 语句,其中一些连接可能属于一个数据库服务器,而其他连接可能属于另一个数据库服务器,依此类推。
该代码确保满足两个条件:
- SQL 语句在可用的数据库服务器上并行运行。
- 在同一个数据库服务器中,SQL 语句异步运行,但按顺序运行。
给定每个数据库服务器的 N 个数据库连接,在聚合结束时将有一个连接Task
,执行具有以下效果:
- 为 db conn 1 执行 SQL
- 完成上一步后,为 db conn 2 执行 SQL
- 完成前面的操作后,为 db conn 3 执行 SQL
- ...
- 完成上一步后,为 db conn N 执行 SQL
- 完成上一步后,为 db conn 2 执行 SQL
我的问题是,除了第一个数据库连接之外,现在异常丢失了。我知道我应该检查_
参数并以某种方式处理_.Exception
延续函数内的属性。我想知道是否有一种优雅的方式来做到这一点。
有任何想法吗?