我正在查询一些员工的 sql 数据库。当我收到这些员工时,我会使用 Parallel.ForEach 循环每个员工。
我循环从数据库中检索到的员工的唯一原因是扩展了一些我不想弄乱数据库的属性。
在这个例子中,我试图在循环中为当前员工设置 Avatar,但始终只有三分之一的员工被设置,其他员工 Avatar 都没有被设置为正确的 URI。基本上,我使用头像的文件名并构建用户文件夹的完整路径。
我在这里做错了什么,每个员工的头像都没有更新到他们目录的完整路径,就像唯一一个正在设置的?并行堆栈和深四
我确定我的代码格式不正确。我看过那个并行任务,它确实在 6 个线程上创建了 4 个并行任务。
有人可以向我指出格式化代码以使用 Parallel 的正确方法吗?
另外,有一件事,如果我return await Task.Run()=>
从 GetEmployees 方法中删除,我会收到无法完成任务的错误,因为其他一些任务首先被钓鱼。
Parallel 的行为就好像它只是为一名员工设置一个 Avatars。
- -呼叫者
public async static Task<List<uspGetEmployees_Result>> GetEmployess(int professionalID, int startIndex, int pageSize, string where, string equals)
{
var httpCurrent = HttpContext.Current;
return await Task.Run(() =>
{
List<uspGetEmployees_Result> emps = null;
try
{
using (AFCCInc_ComEntities db = new AFCCInc_ComEntities())
{
var tempEmps = db.uspGetEmployees(professionalID, startIndex, pageSize, where, equals);
if (tempEmps != null)
{
emps = tempEmps.ToList<uspGetEmployees_Result>();
Parallel.ForEach<uspGetEmployees_Result>(
emps,
async (e) =>
{
e.Avatar = await Task.Run(() => BuildUserFilePath(e.Avatar, e.UserId, httpCurrent, true));
}
);
};
}
}
catch (SqlException ex)
{
throw ex;
};
return emps;
});
}
--被调用者
static string BuildUserFilePath(object fileName, object userProviderKey, HttpContext context, bool resolveForClient = false)
{
return string.Format("{0}/{1}/{2}",
resolveForClient ?
context.Request.Url.AbsoluteUri.Replace(context.Request.Url.PathAndQuery, "") : "~",
_membersFolderPath + AFCCIncSecurity.Folder.GetEncryptNameForSiteMemberFolder(userProviderKey.ToString(), _cryptPassword),
fileName.ToString());
}
- - - - - - - - - - - - - - - - - - - - 编辑 - - - - - --------------------------
我在大家的帮助下使用的最终代码。非常感谢!
public async static Task<List<uspGetEmployees_Result>> GetEmployess(int professionalID, int startIndex, int pageSize, string where, string equals)
{
var httpCurrent = HttpContext.Current;
List<uspGetEmployees_Result> emps = null;
using (AFCCInc_ComEntities db = new AFCCInc_ComEntities())
{
emps = await Task.Run(() => (db.uspGetEmployees(professionalID, startIndex, pageSize, where, equals) ?? Enumerable.Empty<uspGetEmployees_Result>()).ToList());
if (emps.Count() == 0) { return null; }
int skip = 0;
while (true)
{
// Do parallel processing in "waves".
var tasks = emps
.Take(Environment.ProcessorCount)
.Select(e => Task.Run(() => e.Avatar = BuildUserFilePath(e.Avatar, e.UserId, httpCurrent, true))) // No await here - we just want the tasks.
.Skip(skip)
.ToArray();
if (tasks.Length == 0) { break; }
skip += Environment.ProcessorCount;
await Task.WhenAll(tasks);
};
}
return emps;
}