4

私はまだこれらのテクノロジーにかなり慣れていません。ここでの本当の問題は、コンソール アプリでスレッドごとにセッションを管理する方法です。現在、シングル スレッドとして実行すると、すべて問題ありません。マルチスレッド モデルに切り替えるとすぐに、セッション レベルで競合が発生し始めます (Session オブジェクトは設計上アドセーフではないため) KeyNotFound 例外 (とりわけ) がスローされ始めます。

Web アプリでは、次のようにします。

    /// <summary>
    /// Due to issues on IIS7, the NHibernate initialization cannot reside in Init() but
    /// must only be called once.  Consequently, we invoke a thread-safe singleton class to
    /// ensure it's only initialized once.
    /// </summary>
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        NHibernateInitializer.Instance().InitializeNHibernateOnce(
            () => InitializeNHibernateSession());
    }

    /// <summary>
    /// If you need to communicate to multiple databases, you'd add a line to this method to
    /// initialize the other database as well.
    /// </summary>
    private void InitializeNHibernateSession()
    {            

        var path = ConfigurationManager.AppSettings["NHibernateConfig"];
        NHibernateSession.Init(
            webSessionStorage,
            new string[] { Server.MapPath("~/bin/foo.Data.dll") },
            new AutoPersistenceModelGenerator().Generate(),
            Server.MapPath("~/App_Configuration/" + path ));
    }

// sample of my console app... very simple
static void Main(string[] args)
{
  InitializeNHibernateSession();
  while(true)
  {
    Task.Factory.StartNew(() => SomeAwesomeLongRunningPieceOfWork());
  }
}

これは基本的に、global.asax のスレッド (Web 要求) ごとに 1 回初期化を実行します。

コンソール アプリでこれ (セッション管理) を設定する方法についてのアイデアはありますか?

4

1 に答える 1

7

これは私のために働いた:

// Three threads:
for (int i = 0; i < 3; i++)
{
   Thread curThread = new Thread(StartThread);
   curThread.Start();
}

private void StartThread()
{
      NHibernateInitializer.Instance().InitializeNHibernateOnce(InitializeNHibernateSession);
      SomeAwesomeLongRunningPieceOfWork();            
}

private void InitializeNHibernateSession()
{
   var path = ConfigurationManager.AppSettings["NHibernateConfig"];

   NHibernateSession.Init(
      new ThreadSessionStorage(),
      new string[] { "foo.Data.dll" },
      new AutoPersistenceModelGenerator().Generate(),
      "./App_Configuration/" + path);
}

キーは、私が取得したこのクラスでした:

http://groups.google.com/group/sharp-architecture/browse_thread/thread/ce3d9c34bc2da629?fwc=1 http://groups.google.com/group/sharp-architecture/browse_thread/thread/51794671c91bc5e9/386efc30d4c0bf16#386efc30d4c0bf16

public class ThreadSessionStorage : ISessionStorage
{
    [ThreadStatic]
    private static ISession _session;
    public ISession Session
    {
        get
        {
            return _session;
        }
        set
        {
            _session = value;
        }
    }

    public ISession GetSessionForKey(string factoryKey)
    {
        return Session;
    }

    public void SetSessionForKey(string factoryKey, ISession session)
    {
        Session = session;
    }

    public IEnumerable<ISession> GetAllSessions()
    {
        return new List<ISession>() { Session };
    }
}

そして、それはうまく機能します。

于 2011-08-31T22:06:46.957 に答える