2009-04-28 15 views
6

Tenemos una aplicación de escritorio que realiza un conjunto bastante riguroso de cálculos en un hilo de fondo. Partes de este cálculo se realizan en una biblioteca no administrada a la que accedemos a través de interoperabilidad. Lo que estamos descubriendo es que, cuando iniciamos el cálculo, el subproceso de interfaz de usuario deja de responder durante el cálculo. Teníamos la impresión de que el marco manejaría el cambio de hilo para permitir que la IU siga siendo receptiva, pero ese no es el caso. Hemos encontrado que podemos insertar un Thread.Sleep (0) o Application.DoEvents() para permitir que la UI responda. Esto tiene el efecto secundario de ralentizar el cálculo. Además, porciones del cálculo realizado por el código no administrado pueden tardar hasta 30 segundos en completarse, y durante este tiempo la aplicación siempre deja de responder. El cálculo completo puede tardar de dos a cinco minutos en completarse..NET Threading Model and Application.DoEvents vs. Thread.Sleep

Esto conduce a las siguientes preguntas:

  • ¿Cuál es el modelo de hilos marco .NET con respecto a la interfaz de usuario y la interoperabilidad?
  • ¿Somos incorrectos al suponer que el marco debe manejar el cambio de subprocesos entre el fondo y los subprocesos de la interfaz de usuario?
  • ¿Cuál es la diferencia entre usar Thread.Sleep y Application.DoEvents en esta situación, y se prefiere uno sobre el otro?
+0

NOTA: muy viejo Q & A; busca discusiones más recientes para obtener buenas respuestas sobre las soluciones disponibles en la actualidad. – ToolmakerSteve

Respuesta

2

Puede disminuir la prioridad de su hilo de fondo, por lo que será reemplazado más por el sistema operativo. Si tiene algún conocimiento de dominio que lo lleve a querer controlar cuándo se apropia, podría ir con Thread.Sleep (0), que renuncia a su timeslice si hay otro hilo esperando.

Application.DoEvents bombea la cola de mensajes de Windows. Esto hará que su aplicación responda a eventos como las pulsaciones de teclas o el tamaño de la ventana. Thread.Sleep hará que su hilo sea reemplazado (o tal vez no, en el caso de Thread.Sleep (0)).

Lea también Threading in C#

0

La forma correcta de hacerlo es mediante el uso de devoluciones de llamada, sin embargo. Vea el modelo de Silverlight de usar métodos asíncronos (para recuperar datos del servicio web, por ejemplo). Sé que esta pregunta es "respondida", pero la respuesta no es ideal en mi humilde opinión.

2

Su mejor opción es crear su propio Thread. DoEvents y Thread.Sleep(0) bloquea el cálculo, ralentizándolo. Puede envolver sus llamadas a DLL en un delegado ThreadStart o un delegado ParameterizedThreadStart y usar el nombre de delegado como parámetro al crear una instancia del Thread. A partir de ahí, todo lo que tiene que hacer es llamar al método de inicio Thread.