質問を簡単にするために、スレッドを使用して文字列の置換をオンザフライで更新するとします。私の実際のコードでは、スレッドが必要です。私はこの簡単な例でそれを避けることができることを知っています。
したがって、私のソフトウェアには2つのフィールドがあります。ユーザーはファイルを選択し、(一種の)正規表現を記述して、文を入力すると同時に変更の結果を確認します。ユーザーがファイルを選択したときにスレッドを開始します(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); :別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。私はこの例外についてたくさん読みましたが、私はそれを理解していません。
これを修正するために、コードをディスパッチャーで囲みます。メカニズムはわかりませんが、機能します。それが正しいかパフォーマンスかはわかりませんが、機能します。
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命令が表示されます。私のコードは多くの作業を行う必要がありますが、これを遅滞なく行うことが最善の方法であるかどうかはわかりません。ディスパッチャの有用性と優れた実践?