【发布时间】:2013-02-14 10:03:05
【问题描述】:
在我的文件搜索应用程序中,我无法刷新 GUI (OnPropertyChanged)
我从所有检查的目录开始:
foreach (string folderPath in dirList) {
this.Search (fileSearchPattern, folderPath);
}
在这种方法中,我启动了一个后台工作人员...
public void Search(string fileSearchPattern, string folderPath)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += BackgroundSearch;
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundSearchCompleted);
bw.RunWorkerAsync(new string[] { fileSearchPattern, folderPath });
}
...我得到当前文件夹路径的文件列表:
private void BackgroundSearch(object sender, DoWorkEventArgs e)
{
e.Result = new HashSet<string>(
GetFileList(
(e.Argument as string[])[0],
(e.Argument as string[])[1]));
}
当我拥有文件列表时,我会触发一个事件以将项目添加到我的结果数据表中:
void BackgroundSearchCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (this.ItemsAdded != null)
{
// fire event files found:
this.ItemsAdded(e.Result as HashSet<string>);
}
}
// -------------------------------------------------------------------------------------------
这是事件 ItemsAdded 的事件处理程序。 在这里我再次启动一个后台工作者来获取所有文件的文件信息:
public void AddItems(HashSet<string> fileNames)
{
if (fileNames.Count > 0)
{
lock (this.searchResult)
{
this.searchResult.BeginLoadData();
foreach (string n in fileNames)
{
this.searchResult.Rows.Add(
new object[] {null, null, null, null, null, null,
n // Filename
});
}
this.searchResult.EndLoadData();
}
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += BackgroundFileInfo;
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundSearchCompleted);
bw.RunWorkerAsync();
}
}
private void BackgroundFileInfo(object sender, DoWorkEventArgs e)
{
lock (this.searchResult)
{
foreach (DataRow row in this.searchResult.Rows)
{
FileInfo fi = new FileInfo(row["FULL_NAME"].ToString());
row.BeginEdit();
row["FILE_NAME"] = fi.Name;
row["DIRECTORY_NAME"] = fi.DirectoryName;
row["ATTRIB"] = fi.Attributes;
row["CREATION"] = fi.CreationTime.ToShortDateString() + " " +
fi.CreationTime.ToShortTimeString();
row["LAST_WRITE"] = fi.LastWriteTime.ToShortDateString() + " " +
fi.LastWriteTime.ToShortTimeString();
row["LAST_ACCESS"] = fi.LastAccessTime.ToShortDateString() + " " +
fi.LastAccessTime.ToShortTimeString();
row.EndEdit();
}
this.searchResult.AcceptChanges();
}
}
}
获取文件信息完成后,我想刷新我的 GUI, 但在这里我得到一个异常“实例为空”(或类似的东西)
void BackgroundFileInfoCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lock (this.searchResult)
{
OnPropertyChanged("SearchResult"); // <<== HERE I HAVE AN EXCEPTION!!!
}
}
这个错误背后的原因是什么?
【问题讨论】:
-
你真的应该使用一个单独的对象来持有锁。只需创建一个
Object lock并锁定它,而不是searchResult变量。 -
异常有一个类型和一个堆栈跟踪。请准确地将它们添加到您的问题中。没有他们,我们什么都猜不出来。问题不在于您发布的代码。
-
你也可以只发布整个错误,目前还不清楚你发布的内容有什么问题。
-
这里你可以找到更多关于错误的信息:s14.directupload.net/file/d/3180/y3gd3vyh_png.htms1.directupload.net/file/d/3180/5nl2pcnv_png.htm Stacktrace 太长,但这是一个简短的版本:
-
ItemContainerGenerator.Remove * ItemContainerGenerator.System.Windows.Controls.Primitives.IRecyclingItemContainerGenerator.Recycle * VirtualizingStackPanel.CleanupRange * VirtualizingStackPanel.CleanupContainers * VirtualizingStackPanel.MeasureOverride * Controls.Primitives.DataGridRowsPresenter.MeasureOverride(大小约束)* FrameworkElement.MeasureCore(Size availableSize) * UIElement.Measure(Size availableSize) * ContextLayoutManager.UpdateLayout()
标签: c# wpf multithreading exception user-interface