7

이 코드에서이 오류가 어떻게 발생하는지 정말로 이해하지 못합니다. 코드를 직접 확인하십시오.보호 된 메모리를 읽거나 쓰려고 시도했습니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다.

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

이제이 코드는 오류가 발생한 곳입니다. 나는 또한이 오류는 전체 소프트웨어 던져 오류가 발생합니다 스크린 샷을

 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 
     { 

     } 
    } 

를 부착하고 난 새 스레드에서 그들을 호출 오전에도 :(

이 줄 던지는 오류 System.Windows.Threading.Dispatcher을 작동이 중지됩니다. 실행();

enter image description here

을 또한 확인 스크린 샷하세요 0

C# 4.0 WPF

+0

실제로'Task'에있는 스레드와'Thread'에있는 * 두 개의 스레드를 사용하고 있습니다. 스레드의 시작 코드로 실행하려는 코드를 배치하는 것이 좋습니다. – casperOne

+0

@casperOne 나는 여전히 응용 프로그램이 충돌하는 것을 시도했다. 그리고 이것은 잠시 후에 즉시 일어나지 않습니다. 그것은 30 분처럼 실행 후 충돌합니다. 충돌 시간이 변경됩니다. – MonsterMMORPG

+0

아니, 그들은 당신의 기억이 깨 졌다고 말한다. 그렇게되어야합니다! (btw는 내가 '불특정 오류'이후에 만난 가장 멍청한 오류 메시지입니다.) – leppie

답변

0

스레드 기능으로 람다를 사용하고 있습니다. 이 람다는 새로운 스레드에서 호출됩니다. 순간에 스레드가 실제로 만들어지면 로컬 변수 srUrl 인 사용자가 제공하는 인수를 찾게됩니다. 그러나이 때 함수 (dispatcherTimer_Tick)가 이미 종료되어 srUrl이 스택이 더 이상 제대로 정의되지 않습니다 (따라서 액세스 위반). 쉬운 수정은 클래스에 변수를 정의하고 거기에 srLoc을 빠르게 채우는 것입니다. 보다 적절한 용액 실제로 인수로 srLoc 합격이다

() => 
{ 
    startNewWindow(srUrl); 
} 

이제 함수 레퍼런스 및 문자열의 적당한 복사본 함수 호출 동안 저장

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

이되고, 그것은 '케이 원래 srUrl은 스레드가 시작될 때까지 범위를 벗어났습니다. 작업 팩토리가 인수 배열을 전달할 수 있는지 여부는 확실하지 않습니다. 디스패처는 일반적으로이 작업에 과부하가 있으므로 창에서 처리하도록하고 싶을 수 있습니다.

이제 실제로이 작업을 몇 번 수행하므로 전달할 때마다 인수를 래핑해야 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 사실 나는 파일에서 URL을 읽는 다른 응용 프로그램을 작성하여 내 문제를 해결했습니다. 그래서 나는 새로운 창 대신 exes를 시작하고 있습니다. 때때로 이러한 새로운 exes는 오류를 주지만 소프트웨어는 계속 실행됩니다. :) 그러나 당신의 대답은 정말 전문적입니다. – MonsterMMORPG

+1

@MonsterMMORPG이 답변은 논리적으로 들리 겠지만 잘못되었습니다. 클로저는 지역 변수 (자유 변수라고 함)를 캡처합니다. 여기를 참고하십시오 : http://www.codethinked.com/c-closures-explained – ChrisWue

+0

이것이 사실이라면 윈도우를 보여주기 전에 코드가 깨질 것입니다. 창을 표시 한 후 srUrl이 사용되지 않습니다. – surfen

1

얼마 전 비슷한 문제가있었습니다.

창이 범위를 벗어나서 가비지 수집기가이를 손상 시키므로 오류가 발생합니다.

ShowDialog()을 사용하면 문제가 해결됩니다. 이렇게하면 창은 호출 스레드에서만 모달이되므로 다른 스레드를 차단하지 않습니다.

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

사실이라면 ...로드 된 이벤트에서 이벤트를 설정하고 델리게이트를 종료하기 전에 해당 이벤트를 기다리면 비슷한 것을 할 수 있습니다. – Yaur

+0

이것은 의미가 있지만 새로 만든 창의 UI를 차단하지 않습니까? – surfen

+0

답변 해 주셔서 감사합니다. 지금 시험해 볼거야. – MonsterMMORPG

2

저는 고객과 함께이 문제를 다뤄 왔으며 여기에 제가 발견 한 것이 있습니다.

많은 스레딩 및 백그라운드 작업자 처리를 수행하는 WPF 응용 프로그램에서 작업하고 있습니다. 갑자기이 예외가 발생하여 파기를 시작했습니다. 발생 된 것으로 나타납니다 무엇

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

는 백그라운드 작업자가 작업을 마무리하고 실행에서 반환하는 것입니다 : 내가 마지막으로 조사의 약 한 시간 후 범인을 발견.그러나 해당 백그라운드 작업자 내부에서 작성된 스레드는 처리가 완료되지 않았으며 스레드가 작성된 스레드가 이미 범위를 벗어남에 따라 AccessViolationException이 발생합니다.

이 문제를 디버깅하려면 예외가 발생하는 곳을주의 깊게 살펴보고 호출 스택을 면밀히 검토하는 것이 좋습니다. 호출 스택은 스레드 내부에 있는지 여부에 따라 파괴되었거나 손실되었을 수도 있습니다. 예외가 발생합니다.

관련 문제

 관련 문제