tutorial español ejemplos c# .net wpf multithreading datagrid

c# - ejemplos - xaml pdf español



Acceso a la IU(Principal) Enhebrar de forma segura en WPF (3)

La mejor forma de hacerlo sería obtener un SynchronizationContext partir del subproceso UI y usarlo. Esta clase resume las llamadas de clasificación a otros hilos y facilita las pruebas (en contraste con el uso del Dispatcher de WPF directamente). Por ejemplo:

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); } }

Tengo una aplicación que actualiza mi cuadrícula de datos cada vez que un archivo de registro que estoy viendo se actualiza (anexado con texto nuevo) de la siguiente manera:

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); }

Cuando se genera el evento para FileWatcher, porque crea un hilo separado, cuando intento ejecutar dataGridRows.Add (ds); para agregar la nueva fila, el programa simplemente se bloquea sin ninguna advertencia durante el modo de depuración.

En Winforms, esto se solucionó fácilmente utilizando la función Invoke, pero no estoy seguro de cómo hacerlo en WPF.


Puedes usar

Dispatcher.Invoke(Delegate, object[])

en el despachador de la Application (o de cualquier UIElement ).

Puedes usarlo por ejemplo así:

Application.Current.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));

o

someControl.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));


Utilice [Dispatcher.Invoke(DispatcherPriority, Delegate)] para cambiar la UI de otro hilo o de fondo.

Paso 1 Use los siguientes espacios de nombres

using System.Windows; using System.Threading; using System.Windows.Threading;

Paso 2 Coloque la siguiente línea donde necesita actualizar la interfaz de usuario

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { //Update UI here }));

Sintaxis

[BrowsableAttribute(false)] public object Invoke( DispatcherPriority priority, Delegate method )

Parámetros

priority

Tipo: System.Windows.Threading.DispatcherPriority

La prioridad, en relación con las otras operaciones pendientes en la cola de eventos de Dispatcher, se invoca al método especificado.

method

Tipo: System.Delegate

Un delegado en un método que no toma argumentos, que se envía a la cola de eventos de Dispatcher.

Valor de retorno

Tipo: System.Object

El valor devuelto por el delegado invocado o nulo si el delegado no tiene valor devuelto.

Información de versión

Disponible desde .NET Framework 3.0