我在async中调用NHibernate的方法有什么问题吗

本文关键字:什么 问题 方法 async 调用 NHibernate 我在 | 更新日期: 2023-09-27 18:24:54

我正在尝试用NHibernate实现Identity的IUserStore<TUser, in TKey>,它缺少IUserStore所需的异步方法。这是我在调度阻塞调用并使方法异步方面的无知尝试:

public class QsaasUserStore<TLogin> : IUserStore<QsaasUser<TLogin>, int> where TLogin : QsaasUserLogin<int>
{
    public Task CreateAsync(QsaasUser<TLogin> user)
    {
        var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
        return Task.Factory.StartNew(() => session.Save(user))
            .ContinueWith(ex => Trace.TraceError(ex?.Exception?.Message ?? "Strange task fault"), TaskContinuationOptions.OnlyOnFaulted);
    }
}

我从最初的谷歌搜索中收集到了以上内容,对我来说似乎还可以,但我认为我可以在异常处理方面做得更好。

我在async中调用NHibernate的方法有什么问题吗

NHibernate会话不是线程安全的。

您在一个线程上检索会话,然后在另一个线程中调用Save。这可能有效,甚至可能在大多数时候都有效,但你处于"未定义行为"的领域。

您正在实现的接口要求您返回一个任务。您可以在不涉及后台线程的情况下实现此约束。

public class QsaasUserStore<TLogin> : IUserStore<QsaasUser<TLogin>, int> where TLogin : QsaasUserLogin<int>
{
    public Task CreateAsync(QsaasUser<TLogin> user)
    {
        var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
        session.Save(user);
        return Task.FromResult(0);
    }
}

如果您真的想在工作线程上运行它,那么使用后台线程来检索会话并调用Save。只有当您的SessionFactory足够聪明,可以将不同的会话映射到不同的线程时,这才会起作用。

public Task CreateAsync(QsaasUser<TLogin> user)
    {
        return Task.Factory.StartNew(() => {
               var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
                session.Save(user);
        }).ContinueWith(ex => Trace.TraceError(ex?.Exception?.Message ?? "Strange task fault"), TaskContinuationOptions.OnlyOnFaulted);
    }