为了让我的问题保持简单,让我们说我使用线程动态更新字符串中的替换。在我的真实代码中,我需要一个线程。我知道我可以在这个简单的例子中避免它。
所以,我的软件有两个领域。用户选择一个文件,编写一个(某种)正则表达式并在输入句子的同时查看修改结果。我在用户选择文件时启动线程(请参阅 listViewFiles_SelectionChanged 方法)。我的线程的工作是在 DoWork 方法中。
public void DoWork()
{
while (true)
{
FileData fileData = _selectedFile;
if (fileData != null)
{
string name = fileData.FileName;
string searchRegEx = GenerateRegex(_searchTextBox.Text);
string replacement = _replaceTextBox.Text;
name = Regex.Replace(name, searchRegEx, replacement);
/*
foreach (var action in _actionCollection)
{
name = action.Rename(name);
}*/
_searchSample.Content = fileData.FileName;
_replaceSample.Content = name;
}
Thread.Sleep(1000);
}
}
private void listViewFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_selectedFile = listViewFiles.SelectedItem as FileData;
_thread.Start();
}
当我的线程做他的工作时,我在行字符串 searchRegEx = GenerateRegex(_searchTextBox.Text); 上遇到异常。:调用线程无法访问此对象,因为不同的线程拥有它。我读了很多关于这个异常的内容,但我不明白。
为了解决这个问题,我用 Dispatcher 包围了我的代码。我不明白机制,但它的工作原理。我不知道它是否正确或高效,但它有效。
public void DoWork()
{
while (true)
{
FileData fileData = _selectedFile;
if (fileData != null)
{
//use Window.Dispatcher
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate()
{
string name = fileData.FileName;
string searchRegEx = GenerateRegex(_searchTextBox.Text);
string replacement = _replaceTextBox.Text;
name = Regex.Replace(name, searchRegEx, replacement);
/*
foreach (var action in _actionCollection)
{
name = action.Rename(name);
}*/
_searchSample.Content = fileData.FileName;
_replaceSample.Content = name;
}));
}
Thread.Sleep(1000);
}
}
private void listViewFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_selectedFile = listViewFiles.SelectedItem as FileData;
_thread.Start();
}
我想知道这段代码是否正确且正确。您会在评论中看到 foreach 指令。我的代码应该做很多工作,我不知道在 delagate 中这样做是否是最好的方法。Dispatcher 的实用性和良好实践?