Estoy trabajando con una aplicación de Windows Forms que usa NHibernate como ORM. Nuestro patrón habitual se parece a:

  1. Obtenga el gráfico de objetos de la base de datos y complete la GUI
  2. Permitir al usuario editar datos en GUI
  3. Guardar el gráfico de objetos en la base de datos

Esta noción de unidad de trabajo requiere que la sesión de NHibernate viva tanto tiempo como sea necesario para que el usuario edite los datos y presione el botón Guardar. Por lo tanto, se crea una instancia de nuestra sesión como parte del paso 1 y se elimina como parte del paso 3.

Ahora, quiero mostrar una animación de barra de progreso indeterminada durante la operación de guardado. Por lo tanto, la sesión no puede vivir en el hilo de la GUI, ya que eso haría que la animación se congelara si el ahorro lleva tiempo.

¿Cuál es la mejor forma de resolver este problema?

2
Tormod Fjeldskår 24 ene. 2012 a las 12:36

1 respuesta

La mejor respuesta

La solución más sencilla sería derivar un trabajador en segundo plano:

BackgroundWorker _worker;

void OnSaveButtonClicked(...)
{
    // Update your entities with the data entered by the user, e.g.:
    _settings.UserName = textBoxUserName.Text

    _worker = new BackgroundWorker();
    _worker.WorkerCompleted += (s, e) => { /* Saving completed,
                                              hide progress bar */ };
    _worker.DoWork += (s, e) =>
    {
        _session.SaveOrUpdate(_settings);
    };

    // Show progress bar:
    // progressBar.Show...    

    _worker.RunWorkerAsync();
}
4
Daniel Hilgarth 24 ene. 2012 a las 13:22
Pero eso significa que el método SaveOrUpdate se llama desde un subproceso del grupo de subprocesos, no desde el subproceso en el que se creó una instancia de la sesión, ¿no es así?
 – 
Tormod Fjeldskår
24 ene. 2012 a las 13:30
@ TormodFjeldskår: Correcto. ¿Es eso un problema?
 – 
Daniel Hilgarth
24 ene. 2012 a las 13:57
Si, eso es un problema. De la documentación: "¡La ISession no es segura para subprocesos! Nunca acceda a la misma ISession en dos subprocesos simultáneos. ¡Una ISession suele ser una única unidad de trabajo!" Ref: nhforge.org/doc/nh/en/index. html # transacciones-hilos
 – 
Tormod Fjeldskår
24 ene. 2012 a las 14:50
4
@ TormodFjeldskår: Está malinterpretando esto, pero está escrito de una manera que facilita la interpretación incorrecta. Debería leerse como "Nunca acceda a la misma ISession simultáneamente desde dos subprocesos". En el código que te di, accedes a la sesión siempre en solo uno de los dos hilos. Consulte también esto: nhprof.com/Learn/Alerts/CrossThreadSessionUsage, especialmente estas partes: " Hay escenarios válidos para el uso de sesiones de subprocesos cruzados (carga en segundo plano con sincronización cuidadosa, sesión de expansión de múltiples solicitudes) "y (cont.)
 – 
Daniel Hilgarth
24 ene. 2012 a las 14:54
2
(cont.) "Si está utilizando la sesión en varios subprocesos intencionalmente y está seguro de que está serializando correctamente el acceso a ella , puede ignorar esta alerta con seguridad". Y eso es exactamente lo que estamos haciendo: estamos serializando correctamente el acceso a él , accediendo solo desde un hilo a la vez.
 – 
Daniel Hilgarth
24 ene. 2012 a las 14:55