«Подпроцесс, выполняющий вызов, не может получить доступ к этому объекту, поскольку его владельцем является другой поток». Исключение ASYNC / AWAIT WPF C # - PullRequest
0 голосов
/ 29 июня 2018

У меня есть этот код:

SecondLog.Opacity = 1;
List<Reporte> Reportes =await Task.Run(() => db_data.TraerReportes(Environment.MachineName, PickFecha.SelectedDate.Value.Date.ToShortDateString()));
    if (Reportes.Count  != 0)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Nombre del Proceso");
        dt.Columns.Add("Tiempo Activo");
        dt.Columns.Add("Hora del Ultimo Reporte");
        foreach (Reporte R in Reportes)
        {
            TimeSpan a = TimeSpan.FromSeconds(R.TiempoActivo);
            var Columna = dt.NewRow();
            Columna["t1"] = R.NombreProceso;
            Columna["t2"] = a.ToString(@"hh\:mm\:ss");
            Columna["t3"] = R.Fecha;

            dt.Rows.Add(Columna);
            }
            GridReportes.DataContext = dt.DefaultView;
        }

Возвращает:

Подпроцесс, выполняющий вызов, не может получить доступ к этому объекту, поскольку владелец является другим потоком "исключение в строке 2 (List Reportes = await Task.Run (() => db_SpixService.TraerReportes (Environment.MachineName, PickFecha.SelectedDate.Value .Date.ToShortDateString ()));)

Почему это?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018
// this is the part that cannot run on another thread, so prepare it
string param = PickFecha.SelectedDate.Value.Date.ToShortDateString();

List<Reporte> Reportes = await Task.Run(() => 
    db_data.TraerReportes(Environment.MachineName, param));

Вам не нужны никакие другие изменения, вам не нужно Control.Invoke().
Предполагая, что TraerReportes не работает с пользовательским интерфейсом.

0 голосов
/ 29 июня 2018

Это исключение происходит потому, что оно находится в другом потоке, чем поток графического интерфейса.

Вы можете обернуть код для доступа к графическому интерфейсу в этом
(вы можете изменить this с действительной ссылкой на объект Window):

this.Dispatcher.Invoke(() =>
{
    // Your code here
});

Не оптимально, но вы можете попробовать это

DateTime myDate;
this.Dispatcher.Invoke(() =>
{
    // Your UI code here
    SecondLog.Opacity = 1;
    myDate = PickFecha.SelectedDate.Value.Date;
});

List<Reporte> Reportes = await Task.Run(() => db_data.TraerReportes(Environment.MachineName, myDate.ToShortDateString()));
if (Reportes.Count != 0)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("Nombre del Proceso");
    dt.Columns.Add("Tiempo Activo");
    dt.Columns.Add("Hora del Ultimo Reporte");
    foreach (Reporte R in Reportes)
    {
        TimeSpan a = TimeSpan.FromSeconds(R.TiempoActivo);
        var Columna = dt.NewRow();
        Columna["t1"] = R.NombreProceso;
        Columna["t2"] = a.ToString(@"hh\:mm\:ss");
        Columna["t3"] = R.Fecha;

        dt.Rows.Add(Columna);
    }

    this.Dispatcher.Invoke(() =>
    {
        GridReportes.DataContext = dt.DefaultView;
    });         
}

Лучше всего отделить это и установить только элементы GUI внутри Invoke

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...