Я запрашиваю базу данных sql для некоторых сотрудников. Когда я получаю этих сотрудников, я зацикливаю каждого из них, используя Parallel.ForEach.
Единственная причина, по которой я зацикливаю сотрудников, которые были извлечены из базы данных, заключается в том, чтобы расширить несколько свойств, которыми я не хочу загромождать базу данных.
Тем не менее, в этом примере я пытаюсь установить аватар для текущего сотрудника в цикле, но всегда устанавливается только один из трех, ни один из других аватаров сотрудников никогда не получает правильный URI. По сути, я беру имя файла аватара и создаю полный путь к папке пользователей.
Что я делаю неправильно здесь, когда аватар каждого сотрудника не обновляется с указанием полного пути к их каталогу, например, единственного, который устанавливается? Параллельный стек и есть в глубокой четверке
Я уверен, что у меня неправильно отформатирован код. Я просмотрел эту параллельную задачу, и она глубоко создает 4 параллельных задачи на 6 потоках.
Может ли кто-нибудь указать мне правильный способ форматирования кода для использования Parallel?
Кроме того, во-первых, если я удаляю return await Task.Run()=>
из метода GetEmployees, я получаю сообщение об ошибке «Не могу завершить задачу, потому что какая-то другая задача вылавливается первой».
Параллель действует так, как будто устанавливает только один из Аватаров для одного из сотрудников.
---Абонент
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;
}
e.Avatar = Task.Run(async () => await BuildUserFilePath(e.Avatar, e.UserId, httpCurrent, true)).Result;
. См. последние пару абзацев в следующем сообщении в блоге Стивена Туба: blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx - person Kirill Shlenskiy   schedule 08.06.2013