7

Realmente no entiendo cómo está ocurriendo este error en este código. Compruebe el código usted mismoIntentó leer o escribir en la memoria protegida. Esto a menudo es una indicación de que otra memoria está corrupta

void dispatcherTimer_Tick(object sender, EventArgs e) 
{ 
    string srUrl = lstLocalIndex[irLocalIndex] + lstMainIndex[irMainIndex].Replace("0;",""); 

    Task.Factory.StartNew(() => 
    { 
     startNewWindow(srUrl); 
    }); 

} 


    void startNewWindow(string srUrl) 
{ 
    NewWindowThread<TitleWindow, string>(c => new TitleWindow(c), srUrl); 
} 

Ahora este código es donde ocurre el error. También voy a adjuntar pantalla

 private void NewWindowThread<T, P>(Func<P, T> constructor, P param) where T : Window 
    { 
     Thread thread = new Thread(() => 
     { 
      T w = constructor(param); 
      w.Show(); 
      w.Closed += (sender, e) => w.Dispatcher.InvokeShutdown(); 
      try 
      { 
       System.Windows.Threading.Dispatcher.Run(); 
      } 
      catch 
      { 

      } 
     }); 
     thread.SetApartmentState(ApartmentState.STA); 
     try 
     { 
      thread.Start(); 
     } 
     catch 
     { 

     } 
    } 

Este error hace que el error tiro software de conjunto y dejar de trabajar a pesar de que les estoy llamando en el nuevo hilo :(

Esta línea error de tiro System.Windows.Threading.Dispatcher. run();

Por favor, compruebe también la captura de pantalla

enter image description here

C# 4.0 WPF

+0

En realidad, utiliza * dos * hilos, el de la 'Tarea' y luego el' Subproceso', mejor simplemente colocar el código que desea ejecutar como código de inicio en el 'Subproceso'. – casperOne

+0

@casperOne También intenté bloquear la aplicación. Y esto está sucediendo después de un tiempo, no al instante. Funciona como 30 minutos y luego se cuelga. El tiempo de colisión cambia. – MonsterMMORPG

+0

No, dicen que tu memoria está rota. ¡Tiene que ser así! (Por cierto, ese es el mensaje de error más tonto que he encontrado después de 'error no especificado'). – leppie

Respuesta

0

Está utilizando un lambda en función hilo. Esta lambda es llamada en un nuevo hilo. En el momento en el que se crea realmente el hilo, buscará el argumento que proporcione, que es una variable local srUrl, pero cuando esto suceda su función (dispatcherTimer_Tick) ya ha salido, por lo que srUrl estará en una parte del pila que ya no está definida correctamente (de ahí la violación de acceso). La solución fácil es definir una variable en la clase y rellenar el srLoc allí rápidamente. Una solución más adecuada es pasar realmente el srLoc como argumento:

() => 
{ 
    startNewWindow(srUrl); 
} 

convierte

(Action<string>){x => {startNewWindow(x);}, 
      new object[] {srUrl} 

Ahora la referencia de funciones y una copia correcta de la cadena se guardan para la llamada a la función, y que doesn' Importa que el srUrl original esté fuera de alcance en el momento en que se inicia el hilo. No estoy seguro de si la fábrica de tareas permite que se pase la matriz de argumentos. los despachadores normalmente tienen una sobrecarga para esto, así que tal vez quieras que tu ventana se encargue de esto.

Ahora realmente hace esto algunas veces, por lo que puede necesitar envolver los argumentos cada vez que se pasan.

+0

Gracias por responder. En realidad, resolví mi problema escribiendo otra aplicación que lee la url del archivo. Así que estoy empezando ahora en lugar de nuevas ventanas. Algunas veces estos nuevos exes dan errores pero el software continúa ejecutándose :) Pero tu respuesta es realmente profesional, me gusta. – MonsterMMORPG

+1

@MonsterMMORPG Esta respuesta puede sonar lógica pero incorrecta. El cierre capturará la variable local (que se llama variable libre). Vea también aquí: http://www.codethinked.com/c-closures-explained – ChrisWue

+0

Si esto fuera cierto, su código se rompería incluso antes de mostrar la ventana. Después de mostrar la ventana, srUrl no se está utilizando. – surfen

1

Tuve un problema similar hace algún tiempo.

El error ocurre porque su ventana queda fuera de alcance y el recolector de basura lo destruye.

El uso de ShowDialog() debería resolver el problema. Tenga en cuenta que hacer esto no bloqueará otros subprocesos porque la ventana solo será modal en el subproceso de llamada.

private void NewWindowThread<T, P>(Func<P, T> constructor, P param) where T : Window 
{ 
    Thread thread = new Thread(() => 
    { 
     System.Windows.Threading.Dispatcher.Run(); 
     T w = constructor(param); 
     w.ShowDialog(); 
     w.Dispatcher.InvokeShutdown(); 
    }); 
    thread.SetApartmentState(ApartmentState.STA); 
    try 
    { 
     thread.Start(); 
    } 
    catch 
    { 
     // log&handle exceptions 
    } 
} 
+0

Si es cierto ... puede hacer algo similar configurando un evento en el evento cargado y esperando ese evento antes de salir del delegado. – Yaur

+0

Esto tiene sentido, pero ¿no bloquearía la interfaz de usuario de la ventana recién creada? – surfen

+0

gracias por la respuesta. voy a intentar ahora. – MonsterMMORPG

2

He estado luchando contra este problema con un cliente y esto es lo que encontré.

Estamos trabajando en una aplicación WPF que realiza una gran cantidad de subprocesos y procesamiento de trabajadores en segundo plano. Esta excepción de repente comenzó a surgir y comencé a cavar. Finalmente encontré el culpable después de una hora de investigar:

 var worker = new BackgroundWorker(); 
     worker.DoWork += (o, ea) => Dispatcher.BeginInvoke(new Action(() => 
     { 
      //do some heavy processing here, plus UI work, then call another method. 

      //inside that other method, I found this: 
      var thread = new Thread(() => 
      { 
       //do some heavy processing. 
      }) { IsBackground = true }; 
      thread.Start(); 
     })); 

lo que parece haber estado sucediendo es que el trabajador fondo está terminando su trabajo y volver de su ejecución.Sin embargo, el subproceso que se crea dentro de ese trabajador de fondo no se procesa y solo regresa para descubrir que el subproceso en el que se creó ya ha salido del alcance, lo que da como resultado AccessViolationException.

Para depurar esto, le sugiero prestar mucha atención a dónde ocurre la excepción y examinar de cerca su pila de llamadas, que puede o no haberse destruido o perdido dependiendo de si está o no dentro de un hilo cuando el excepción se arroja.

Cuestiones relacionadas