Часть моего приложения требует крупномасштабного импорта пользователей, эта информация предоставляется через документ Excel, который загружается через представление.
Из-за размера этого пакета и нескольких других процессов, которые должны быть запущены для каждого пользователя, включая приветственные письма, которые занимают довольно много времени, я решил использовать потоки для этого, чтобы избежать длительных экранов загрузки для пользователя.
Чтобы использовать потоки Мне нужно было сделать несколько переменных доступными для многопоточной функции, в том числе ApplicationUserManager
, HttpRequestBase
и UrlHelper
, которые заполняются функцией ActionResult
, которая запускает эту Thread
Это функция контроллера, которая заполняет эту информацию:
public ActionResult importExternalUsers()
{
BulkUserImportProcessHelperModel helperModel = new BulkUserImportProcessHelperModel();
helperModel.userManager = this.HttpContext.ApplicationInstance.Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); ;
helperModel.urlContext = this.Url;
helperModel.httprequestBase = this.Request;
helperModel.filePath = @"C:\Users\tiaan\Desktop\MultipleUserCreation.xlsx";
Thread thread = new Thread(new ParameterizedThreadStart(bulkUserImportProcess));
thread.Start(helperModel);
return View();
}
Как вы можете видеть, модели заполняются, после чего создается поток. В этом случае я использовал «вспомогательную модель», просто чтобы передать параметры функции, которую я запустил в Thread
, так как я не мог найти простой способ, если он вообще есть, передать несколько параметров функции, предназначенной для многопоточное использование.
Это многопоточная функция, которая импортирует документ Excel и запускает l oop, который регистрирует пользователей:
public static void bulkUserImport(object objectParams)
{
BulkUserImportProcessHelperModel helperModel = (BulkUserImportProcessHelperModel)objectParams;
List<MedicalProfessionalRegistration> usersToReg = IO.InputOutput.ImportExcelDocument(helperModel.filePath);
foreach (var user in usersToReg)
{
AccountController.registerUser(user, helperModel.userManager, helperModel.urlContext, helperModel.httprequestBase);
}
}
Пока что, хотя, вероятно, немного нетрадиционно, все работает. Добавление точки останова в эту функцию после создания переменной helperModel
показывает, что все поля были заполнены должным образом.
Мои проблемы начинаются с функции stati c AccountController
, ответственной за создание пользователей.
public static bool registerUser(MedicalProfessionalRegistration model, ApplicationUserManager userManager, UrlHelper urlHelper, HttpRequestBase request)
{
string password = membershipPasswordGenerator(10, 10, 5, 1);
model.Password = password;
model.ConfirmPassword = password;
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
var result = userManager.Create(user, model.Password);
if (result.Succeeded)
{
IO.Identities.registerUser(user.Id, IO.IdentityRank.User);
IO.Identities.storeUserIdentityMeta(user.Id, model);
string code = userManager.GenerateEmailConfirmationToken(user.Id);
string callbackUrl = urlHelper.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code, rst = "T" }, protocol: request.Url.Scheme);
IO.Email.confirmEmailAccountRegister(user.Email, callbackUrl);
return true;
}
else
{
return false;
}
}
В настоящее время я получаю исключение для
var result = userManager.Create(user, model.Password);
, которое гласит:
Это исключение изначально было выброшено в этот стек вызовов:
System.Data.Entity.Internal.LazyInternalContext.Connection.get ()
Что странно для меня, так это то, что иногда он фактически заполняет базу данных одним пользователем из этого списка, а затем, кажется, не работает на следующая итерация l oop в bulkUserImport
. В то время как в других случаях он почти сразу же выходит из строя с первым.
Я считаю, что это как-то связано с удалением UserManager, как говорит трассировка стека, а также с тем, что userManager null
Этот поток может работать более часа (и IIS сервер был настроен соответствующим образом для этого)
Итак, в конечном итоге, я думаю, это сводится к тому, есть ли способ предотвратить удаление этих полей, или есть что-то еще, что не так с моим logi c вот что я забыл после того, как потратил последний день на то, чтобы возиться с ним?
Заранее спасибо