7

Tôi thực sự không hiểu làm thế nào là lỗi này xảy ra ở mã này. Vui lòng kiểm tra mã cho chính mìnhĐã cố gắng đọc hoặc ghi bộ nhớ được bảo vệ. Đây thường là dấu hiệu cho thấy bộ nhớ khác bị hỏng

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

Bây giờ mã này là nơi xảy ra lỗi. Tôi cũng sẽ đính kèm ảnh chụp màn hình

 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 
     { 

     } 
    } 

Lỗi này gây ra toàn bộ lỗi phần mềm ném và ngừng làm việc mặc dù tôi đang gọi họ trong chủ đề mới :(

Dòng này ném lỗi System.Windows.Threading.Dispatcher. Run();

Vui lòng kiểm tra cũng screenshot

enter image description here

C# 4.0 WPF

+0

Bạn đang sử dụng * hai * chủ đề, một trong 'Task' và sau đó là' Thread', tốt hơn là chỉ đặt mã bạn muốn chạy làm mã khởi động trong 'Thread'. – casperOne

+0

@casperOne Tôi cũng đã thử rằng ứng dụng vẫn gặp sự cố. Và điều này xảy ra sau một thời gian không ngay lập tức. Nó chạy như 30 phút sau đó sụp đổ. Thời gian đổ vỡ thay đổi. – MonsterMMORPG

+0

Không, họ nói rằng bộ nhớ của bạn bị hỏng. Nó phải là như vậy! (btw đó là thông báo lỗi ngu ngốc nhất tôi gặp phải sau 'lỗi không xác định'). – leppie

Trả lời

0

Bạn đang sử dụng hàm lambda làm hàm chuỗi. Lambda này được gọi trên một chủ đề mới. Tại thời điểm thời điểm luồng thực sự được tạo, nó sẽ tìm đối số bạn cung cấp, đó là biến cục bộ srUrl, nhưng vào thời điểm này, hàm của bạn (dispatcherTimer_Tick) đã thoát, vì vậy srUrl sẽ nằm trong phần ngăn xếp không còn được xác định đúng (do đó vi phạm truy cập). Việc sửa chữa dễ dàng là xác định một biến trong lớp và các công cụ srLoc có một cách nhanh chóng. Một giải pháp thích hợp hơn là để thực sự vượt qua srLoc như là đối số:

() => 
{ 
    startNewWindow(srUrl); 
} 

trở thành

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

Bây giờ tài liệu tham khảo chức năng và một bản sao hợp của chuỗi được lưu cho các cuộc gọi chức năng, và nó doesn' t vấn đề rằng các srUrl ban đầu là ra khỏi phạm vi của thời gian thread khởi động in Tôi không chắc liệu các nhà máy nhiệm vụ cho phép các mảng đối số được thông qua. điều phối viên thường có một tình trạng quá tải cho điều này, vì vậy có thể bạn muốn để cho cửa sổ của bạn chăm sóc này.

Bây giờ bạn thực sự làm điều này một vài lần, vì vậy bạn có thể cần phải quấn các đối số mỗi khi chúng được thông qua.

+0

Cảm ơn bạn đã trả lời. Trên thực tế tôi giải quyết vấn đề của tôi thông qua viết một ứng dụng khác mà đọc url từ tập tin. Vì vậy, tôi đang bắt đầu exes bây giờ thay vì cửa sổ mới. Một số lần những exes mới cho lỗi nhưng phần mềm tiếp tục chạy :) Nhưng câu trả lời của bạn là thực sự chuyên nghiệp tôi thích nó. – MonsterMMORPG

+1

@MonsterMMORPG Câu trả lời này có vẻ hợp lý nhưng nó sai. Việc đóng sẽ nắm bắt biến cục bộ (được gọi là biến tự do). Xem thêm tại đây: http://www.codethinked.com/c-closures-explained – ChrisWue

+0

Nếu điều này đúng thì mã của bạn sẽ bị hỏng trước khi hiển thị cửa sổ. Sau khi hiển thị cửa sổ, srUrl không được sử dụng. – surfen

1

Tôi đã gặp vấn đề tương tự cách đây một thời gian.

Lỗi xảy ra vì cửa sổ của bạn nằm ngoài phạm vi và Trình thu gom rác phá hủy nó.

Sử dụng ShowDialog() nên khắc phục sự cố. Lưu ý rằng làm điều này sẽ không chặn các chủ đề khác vì cửa sổ sẽ chỉ là phương thức trong chuỗi chỉ gọi.

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

Nếu đúng ... bạn có thể làm điều gì đó tương tự bằng cách đặt một sự kiện trong sự kiện được tải và chờ sự kiện đó trước khi thoát khỏi đại biểu. – Yaur

+0

Điều này có ý nghĩa nhưng nó sẽ không chặn giao diện người dùng của cửa sổ mới được tạo ra? – surfen

+0

cảm ơn bạn đã trả lời. sẽ thử ngay bây giờ. – MonsterMMORPG

2

Tôi đã chiến đấu với vấn đề này với khách hàng và đây là những gì tôi đã tìm thấy.

Chúng tôi đang làm việc trên một ứng dụng WPF thực hiện rất nhiều luồng và xử lý nhân viên nền. Ngoại lệ này đột nhiên bắt đầu cắt xén và tôi bắt đầu làm một số việc đào bới. Cuối cùng tôi đã tìm ra thủ phạm sau khoảng một tiếng đồng hồ điều tra:

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

gì dường như đã được xảy ra là người lao động nền được hoàn thành công việc của mình và trở về từ thực hiện của nó.Tuy nhiên, luồng được tạo bên trong nhân viên nền đó không được xử lý xong và chỉ trả về để tìm ra rằng luồng nó đã được tạo ra đã đi ra ngoài phạm vi, do đó dẫn đến AccessViolationException. Để sửa lỗi này, tôi khuyên bạn nên chú ý đến nơi ngoại lệ xảy ra và kiểm tra chặt chẽ ngăn xếp cuộc gọi của bạn, có thể có hoặc không bị phá hủy hoặc mất tùy thuộc vào việc bạn có nằm trong một chủ đề hay không khi ngoại lệ bị ném.