7

Ich verstehe wirklich nicht, wie dieser Fehler bei diesem Code passiert. Bitte überprüfen Sie den Code selbstVersuch, geschützten Speicher zu lesen oder zu schreiben. Dies ist oft ein Hinweis darauf, dass anderer Speicher beschädigt ist

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); 
} 

Jetzt ist dieser Code, wo der Fehler passiert. Ich werde auch Screenshot

 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 
     { 

     } 
    } 

Dieser Fehler verursacht gesamte Software throw Fehler anhängen und aufhören zu arbeiten, obwohl ich sie in neuen Thread nenne :(

Diese Linie werfen Fehler System.Windows.Threading.Dispatcher. Run();

Bitte überprüfen Screenshot auch

enter image description here

C# 4.0 WPF

+0

Sie verwenden tatsächlich * zwei * Threads, der eine in der 'Task' und dann den' Thread', besser, um den Code, den Sie als Startup-Code ausführen möchten, einfach in 'Thread' zu platzieren. – casperOne

+0

@casperOne Ich habe auch versucht, dass immer noch Anwendung abstürzt. Und das passiert nach einer Weile nicht sofort. Es läuft wie 30 Minuten und stürzt dann ab. Die Absturzzeit ändert sich. – MonsterMMORPG

+0

Nein, sie sagen, dein Gedächtnis ist gebrochen. Es muss so sein! (Übrigens ist das die dümmste Fehlermeldung, die ich nach einem 'unspezifizierten Fehler' gefunden habe). – leppie

Antwort

0

Sie verwenden Lambda als Thread-Funktion. Dieses Lambda wird in einem neuen Thread aufgerufen. Unter dem Moment ist der Thread tatsächlich erstellt, es wird nach dem von Ihnen gelieferten Argument suchen, das eine lokale Variable srUrl ist, aber wenn dies passiert, ist Ihre Funktion (dispatcherTimer_Tick) bereits beendet, also wird srUrl in einem Teil des Stack, der nicht mehr richtig definiert ist (daher die Zugriffsverletzung). Die einfache Lösung besteht darin, eine Variable in der Klasse zu definieren und das srLoc dort schnell zu stopfen. Eine geeignete Lösung ist, um tatsächlich die srLoc als Argument übergeben:

() => 
{ 
    startNewWindow(srUrl); 
} 

wird

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

die Funktionsreferenz Jetzt und eine richtige Kopie des Strings sind für den Funktionsaufruf gespeichert, und es doesn‘ Es ist wichtig, dass das ursprüngliche srUrl zu dem Zeitpunkt, zu dem der Thread gestartet wird, nicht mehr im Bereich ist. Ich bin mir nicht sicher, ob die Task-Factory die Übergabe des Argumentarrays zulässt. Dispatcher haben normalerweise eine Überlastung, also wollen Sie vielleicht Ihr Fenster dafür sorgen lassen.

Jetzt machen Sie das tatsächlich ein paar Mal, also müssen Sie die Argumente möglicherweise jedes Mal umbrechen, wenn sie übergeben werden.

+0

Danke für die Antwort. Eigentlich habe ich mein Problem gelöst, indem ich eine andere Anwendung geschrieben habe, die die URL aus der Datei liest. So starte ich jetzt exes statt neuer Fenster. Manchmal geben diese neuen Exes Fehler, aber die Software läuft weiter :) Aber deine Antwort ist wirklich professionell, ich mag sie. – MonsterMMORPG

+1

@MonsterMMORPG Diese Antwort klingt logisch, ist aber falsch. Der Abschluss erfasst die lokale Variable (die als freie Variable bezeichnet wird). Siehe auch hier: http://www.codethinked.com/c-closures-explained – ChrisWue

+0

Wenn dies zutrifft, würde Ihr Code brechen, bevor das Fenster angezeigt wird. Nach dem Anzeigen des Fensters wird die srUrl nicht verwendet. – surfen

1

Ich hatte vor einiger Zeit ähnliches Problem.

Der Fehler tritt auf, weil Ihr Fenster den Gültigkeitsbereich verlässt und Garbage Collector es zerstört.

Mit ShowDialog() sollte das Problem lösen. Beachten Sie, dass dadurch andere Threads nicht blockiert werden, da das Fenster nur im aufrufenden Thread modal ist.

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

Wenn true ... können Sie etwas Ähnliches tun, indem Sie ein Ereignis im geladenen Ereignis setzen und auf dieses Ereignis warten, bevor Sie den Delegierten verlassen. – Yaur

+0

Dies ist sinnvoll, aber würde es nicht die Benutzeroberfläche des neu erstellten Fensters blockieren? – surfen

+0

danke für die antwort. Ich werde es jetzt versuchen. – MonsterMMORPG

2

Ich habe dieses Problem mit einem Kunden zu kämpfen und hier ist, was ich gefunden habe.

Wir arbeiten an einer WPF-Anwendung, die eine Menge Threading und Hintergrundverarbeitung verarbeitet. Diese Ausnahme kam plötzlich auf und ich fing an zu graben. Ich fand schließlich die Täter nach etwa einer Stunde zu untersuchen:

 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(); 
     })); 

Was passiert zu haben scheint, ist, dass der Hintergrund Arbeiter seine Arbeit Veredelung und die Rückkehr von seiner Ausführung.Der Thread, der in diesem Hintergrund-Worker erstellt wird, wird jedoch nicht verarbeitet und nur zurückgegeben, um festzustellen, dass der Thread, auf dem es erstellt wurde, bereits den Gültigkeitsbereich überschritten hat, was zu der AccessViolationException geführt hat.

Um dies zu debuggen, würde ich vorschlagen, genau zu beobachten, wo die Ausnahme passiert und genau Ihre Call-Stack, die möglicherweise zerstört oder verloren gegangen sind abhängig davon, ob Sie in einem Thread sind, wenn die Ausnahme wird ausgelöst.