我有一个ObservableCollection
自定义类,它包含一个字符串和一个 int:
public class SearchFile
{
public string path { set; get; }
public int occurrences { set; get; }
}
我想在dataGrid
. 该集合具有在更新时通知的方法,到目前为止,只需将其链接到DataGrid.ItemsSource
(正确的?)。这是网格 XAML(dataGrid1.ItemsSource = files;
在 C# 代码隐藏中):
<DataGrid AutoGenerateColumns="False" Height="260" Name="dataGrid1" VerticalAlignment="Stretch" IsReadOnly="True" ItemsSource="{Binding}" >
<DataGrid.Columns>
<DataGridTextColumn Header="path" Binding="{Binding path}" />
<DataGridTextColumn Header="#" Binding="{Binding occurrences}" />
</DataGrid.Columns>
</DataGrid>
现在事情变得更复杂了。我首先要显示path
默认值occurrence
为零的 s。然后,我想遍历每一个SearchFile
并用计算值更新它occurrence
。这是辅助函数:
public static void AddOccurrences(this ObservableCollection<SearchFile> collection, string path, int occurrences)
{
for(int i = 0; i < collection.Count; i++)
{
if(collection[i].path == path)
{
collection[i].occurrences = occurrences;
break;
}
}
}
这是占位符工作函数:
public static bool searchFile(string path, out int occurences)
{
Thread.Sleep(1000);
occurences = 1;
return true; //for other things; ignore here
}
我正在使用 aBackgroundWorker
作为后台线程。就是这样:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
List<string> allFiles = new List<string>();
//allFiles = some basic directory searching
this.Dispatcher.Invoke(new Action(delegate
{
searchProgressBar.Maximum = allFiles.Count;
files.Clear(); // remove the previous file list to build new one from scratch
}));
/* Create a new list of files with the default occurrences value. */
foreach(var file in allFiles)
{
SearchFile sf = new SearchFile() { path=file, occurrences=0 };
this.Dispatcher.Invoke(new Action(delegate
{
files.Add(sf);
}));
}
/* Add the occurrences. */
foreach(var file in allFiles)
{
++progress; // advance the progress bar
this.Dispatcher.Invoke(new Action(delegate
{
searchProgressBar.Value = progress;
}));
int occurences;
bool result = FileSearcher.searchFile(file, out occurences);
files.AddOccurrences(file, occurences);
}
}
现在当我运行它时,有两个问题。首先,更新进度条的值会引发The calling thread cannot access this object because a different thread owns it.
异常。为什么?它在调度程序中,所以它应该可以正常工作。其次,foreach
循环bool result =...
在行上中断。我将其注释掉并尝试设置int occurences = 1
,然后循环继续进行,但发生了一些奇怪的事情:每当我调用该方法时,它要么全为零,全为一,要么处于中间状态,onez 在看似随机的数字之后开始零)。
为什么?