2015-10-30 29 views
0

我有一個C#(WPF)程序來搜索目錄中的文件,並且我想要一個進度條來顯示搜索目錄中文件的進度(因爲目錄中可能有成千上萬的文件)。爲什麼我在這個C#wpf應用程序中得到這個InvalidOperationException?

我決定使用後臺工作,以便進度條正確更新(這不會發生,但這不是我最大的問題)。

目前發生的事情是它是超級怪異的作品,但大多數時候我得到這個錯誤。唯一一次我沒有得到這個錯誤是,如果我在foreach(document in myDirectory)循環中添加一個MessageBox.Show();來減慢速度並查看它打開的數字文件。然後它每隔一段時間就會出錯。

任何人都可以向我解釋爲什麼我得到這個錯誤,以及如何解決它?另外,如果您認爲有更好的方法來顯示進度條,請不要猶豫,以糾正我在做什麼。

我的錯誤

「System.InvalidOperationException」類型的異常出現在System.dll中,但在用戶代碼中沒有處理

附加信息:該操作已經有OperationCompleted呼籲它和進一步的電話是非法的。

myApp.xaml.cs

BackgroundWorker backgroundWorker1; 

public void searchFiles() 
{ 
    //50 files in the directory 
    int fileCount = 50; 
    int documentCounter = 0; 
    //For every file in the directory 
    foreach(document in myDirectory) 
    { 
    //increment the file count 
    documentCounter++; 
    FileSearchProgressBar(documentCounter, fileCount); 
    } 
} 

private void FileSearchProgressBar(int currentDocNumber, int count) 
{ 
    backgroundWorker1 = new BackgroundWorker(); 
    backgroundWorker1.WorkerReportsProgress = true; 
    backgroundWorker1.DoWork += (obj, ea) => CalculateProgress(currentDocNumber, count); 
    backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(progressReport); 
    backgroundWorker1.RunWorkerAsync(); 
} 

void progressReport(object sender, ProgressChangedEventArgs e) 
{ 
    progBar.Value = e.ProgressPercentage; 
} 

private void CalculateProgress(int currentDocNumber, int count) 
{ 
    //This is where the error is reporting 
    backgroundWorker1.ReportProgress(currentDocNumber * (100/count)); 
} 

EDIT1

堆棧跟蹤

System.InvalidOperationException: This operation has already had OperationCompleted called on it and further calls are illegal. at System.ComponentModel.AsyncOperation.VerifyNotCompleted() at System.ComponentModel.AsyncOperation.Post(SendOrPostCallback d, Object arg) at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress, Object userState) at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress) at HR_Search_Program.MainWindow.CalculateProgress(Int32 currentDocNumber, Int32 count) in c:\Users\myname\Documents\Visual Studio 2013\Projects\myproject\myproject\MainWindow.xaml.cs:line 589

+0

'backgroundWorker1'從哪裏來?你試圖爲每個'document'創建一個,但沒有聲明我們不能告訴範圍。 – HABO

+0

在我看來,跨線程異常嘗試把一個嘗試抓住,看到堆棧跟蹤和張貼在這裏,請 –

+0

@HABO感謝您指出。我添加了聲明。 – trueCamelType

回答

1

你發佈的代碼甚至無法編譯。這在語法上不正確。沒有a good, minimal, complete code example可靠地再現問題,不可能知道問題是什麼,不必介意最好的解決方案。但也有一些線索,在您的文章:

  • 異常明顯,說明你的代碼試圖調用BackgroundWorker對象,表示已經完成的操作上ReportProgress()方法。
  • 啓動BackgroundWorker的代碼將爲您的myDirectory集合中的每個文檔創建一個新實例,並將此新實例的引用分配給單個變量backgroundWorker1

既然你的BackgroundWorker多個實例同時運行,但是隻能跟蹤單個實例的時間,這是最有可能的一個實例啓動後首先完成,和實例更早開始試圖報告進度,但只能使用稍後啓動的實例的引用來執行此操作。由於後來啓動的實例已經完成,拋出異常。

一種修復方法是簡單地將CalculateProgress()方法作爲發送到DoWork事件處理程序的參考BackgroundWorker參考。這樣,BackgroundWorker的每個實例將使用本身來報告進度,而不是嘗試使用最近開始的一個。

但是,首先使用多個BackgroundWorker實例似乎不太可能是一個好主意。一個更好的實現是BackgroundWorker的單個實例,枚舉文檔的循環位於該工作人員的DoWork事件處理程序中。

這是我的希望,以上是足夠的信息,您可以識別您的代碼中的錯誤並修復它。如果沒有,請提供一個很好的代碼示例,以便可以對其進行修改以說明我的意思。

+0

感謝您的最小代碼示例帖子的鏈接。我會盡力實現你今天提到的,如果它不回答我的問題,我會寫一個具有相同問題的小程序,這樣我就可以把它連接起來。再次感謝。 – trueCamelType

相關問題