Saya memiliki aplikasi yang memperbarui datagrid saya setiap kali file log yang saya tonton diperbarui (Ditambahkan dengan teks baru) dengan cara berikut:
private void DGAddRow(string name, FunctionType ft)
{
ASCIIEncoding ascii = new ASCIIEncoding();
CommDGDataSource ds = new CommDGDataSource();
int position = 0;
string[] data_split = ft.Data.Split(' ');
foreach (AttributeType at in ft.Types)
{
if (at.IsAddress)
{
ds.Source = HexString2Ascii(data_split[position]);
ds.Destination = HexString2Ascii(data_split[position+1]);
break;
}
else
{
position += at.Size;
}
}
ds.Protocol = name;
ds.Number = rowCount;
ds.Data = ft.Data;
ds.Time = ft.Time;
dataGridRows.Add(ds);
rowCount++;
}
...
private void FileSystemWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher(Environment.CurrentDirectory);
watcher.Filter = syslogPath;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.EnableRaisingEvents = true;
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
if (File.Exists(syslogPath))
{
string line = GetLine(syslogPath,currentLine);
foreach (CommRuleParser crp in crpList)
{
FunctionType ft = new FunctionType();
if (crp.ParseLine(line, out ft))
{
DGAddRow(crp.Protocol, ft);
}
}
currentLine++;
}
else
MessageBox.Show(UIConstant.COMM_SYSLOG_NON_EXIST_WARNING);
}
Ketika acara dimunculkan untuk FileWatcher, karena itu membuat utas terpisah, ketika saya mencoba menjalankan dataGridRows.Add (ds); untuk menambahkan baris baru, program hanya macet tanpa peringatan apa pun yang diberikan selama mode debug.
Di Winforms, ini mudah diselesaikan dengan memanfaatkan fungsi Invoke tetapi saya tidak yakin bagaimana cara melakukannya di WPF.
Application.Current
karena terlihat lebih bersih bagi saya.Dispatcher.BeginInvoke
. Metode itu hanya mengantrekan delegasi untuk dieksekusi.Cara terbaik untuk melakukannya adalah dengan mendapatkan
SynchronizationContext
dari UI thread dan menggunakannya. Kelas ini memisahkan panggilan marshalling ke thread lain, dan membuat pengujian lebih mudah (berbeda dengan menggunakan WPFDispatcher
secara langsung). Sebagai contoh:class MyViewModel { private readonly SynchronizationContext _syncContext; public MyViewModel() { // we assume this ctor is called from the UI thread! _syncContext = SynchronizationContext.Current; } // ... private void watcher_Changed(object sender, FileSystemEventArgs e) { _syncContext.Post(o => DGAddRow(crp.Protocol, ft), null); } }
sumber
Gunakan [Dispatcher.Invoke (DispatcherPriority, Delegate)] untuk mengubah UI dari thread lain atau dari latar belakang.
LANGKAH 1 . Gunakan ruang nama berikut
using System.Windows; using System.Threading; using System.Windows.Threading;
LANGKAH 2 . Letakkan baris berikut di mana Anda perlu memperbarui UI
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { //Update UI here }));
sumber