Управление сеансами NHibernate в RESTful API с помощью Tasks/ThreadsC#

Место общения программистов C#
Ответить
Anonymous
 Управление сеансами NHibernate в RESTful API с помощью Tasks/Threads

Сообщение Anonymous »

Я создаю набор API. Одним из них является API аутентификации, который возвращает токены JWT. Я пытаюсь реализовать подход «Сессия для каждого действия» с помощью ActionFiltersAttribute. Мой контроллер украшен этим атрибутом:

Код: Выделить всё

public class NHibernateSessionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var session = NHibernateSessionManager.SessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var session = CurrentSessionContext.Unbind(NHibernateSessionManager.SessionFactory)
if (session != null)
{
if (session.Transaction.IsActive)
{
try
{
session.Transaction.Commit();
}
catch
{
session.Transaction.Rollback();
}
}

session.Close();
}
}
}
В чем проблема? Чтобы управлять пользователями с помощью NHibernate вместо Entity Framework, я реализовал все необходимые интерфейсы ASP.NET Identity, и все они возвращают Task. Например, при следующем действии:

Код: Выделить всё

AccountController.cs

public async Task ChangePassword(ChangePasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
model.NewPassword);

if (!result.Succeeded)
{
return GetErrorResult(result);
}

return Ok();
}
Там ChangePasswordAsync вызывает внутри несколько методов, код которых находится внутри новых задач, где SessionFactory.GetCurrentSession() вызывает исключение NullException. Насколько я знаю, потому что это другой поток и контекст.
В коде первая попытка сохранения выполняется без сбоев, а вторая - нет. Дублированный код предназначен только для иллюстрации ситуации.

Код: Выделить всё

UserStore.cs

public System.Threading.Tasks.Task UpdateAsync(UserModel user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
//Here the Session is found
DataProviderI prov = new DataProviderImplGeneric();
prov.Save(user);

return Task.Factory.StartNew(() =>
{
//Here the Session is NOT found
DataProviderI prov2 = new DataProviderImplGeneric();
prov.Save(user);
});
}
Как лучше всего справиться с этим и получить один и тот же ISession во время всего действия?
Насколько мне известно, NHibernate не поддерживает асинхронные вызовы, и я мог бы реорганизовать методы с возвратом типа Task.FromResult(0) в случаях void или Task.FromResult(T), где T является объектом, но я хотел бы знать, если есть еще одно решение, позволяющее воспользоваться преимуществами параллелизма

Подробнее здесь: https://stackoverflow.com/questions/332 ... ks-threads
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»