Не удается запросить свойство у BitmapSource в цикле while в Задаче - PullRequest
0 голосов
/ 24 октября 2018

В моем приложении я открываю данные изображения в задании.Но когда я пытаюсь запросить свойство из BitmapSource внутри цикла while в той же функции, что и при создании изображения, я получаю следующую ошибку:

The calling thread cannot access this object because a different thread owns it

Но когда я вызываю свойство до того, какЦикл while работает без проблем.Насколько я знаю, это все в одной и той же функции?Итак, почему я получаю ошибку?

Код, который дает мне ошибку:

public AnalogInputs()
{
    Task.Run(() =>
    {
       AnalogInputsSimulationTask();
    });
}
private async void AnalogInputsSimulationTask()
{
    BitmapSource bSource = new BitmapImage(new Uri("pack://application:,,,/Images/HBT_Light_Diode_Simulation.bmp"));

    while (true)
    {
        var bytesPerPixel = (bSource.Format.BitsPerPixel + 7) / 8;   //This line gives the error
        await Task.Delay(1);
    }
}

Но когда я форматирую функцию AnalogInputsSimulationTask, как это, она не дает мне ошибку:

private async void AnalogInputsSimulationTask()
{
    BitmapSource bSource = new BitmapImage(new Uri("pack://application:,,,/Images/HBT_Light_Diode_Simulation.bmp"));

    var bytesPerPixel = (bSource.Format.BitsPerPixel + 7) / 8;    //Now there is no error
    while (true)
    {
        await Task.Delay(1);
    }
}

Так как это очень урезанная версия моей проблемы, мне нужен первый формат для работы, я хочу загрузить изображение один раз, а затем делать что-то с ним в цикле while.Но я не могу получить к нему доступ в цикле while.

Я знаю, что эта ошибка обычно возникает, когда вы пытаетесь получить доступ к GUI изнутри Задачи, но сейчас я все делаю в Задаче, и изображение не 't отображается или используется в графическом интерфейсе в любом месте.

1 Ответ

0 голосов
/ 25 октября 2018

Задачи хитрые звери.Если вы ожидаете Task.Delay из потока GUI, вы вернетесь в поток GUI после задержки, потому что продолжение вызывается с использованием контекста синхронизации кода, запустившего задачу, и контекста синхронизации для потока GUI, который вызывается впоток GUI.Когда вы вызываете Task.Run, вы попадаете в поток пула потоков (или выделенный поток, если он долго работает);текущий планировщик задач не поддерживается контекстом синхронизации и будет вызываться в потоке пула потоков (обычно, но не обязательно, в другом потоке).

В вашем коде ваш BitmapSource создается в первом потоке потоков пула, полученном из Task.Run.Поэтому к нему можно получить доступ только из этой темы.Когда вы ожидаете Задержку, продолжение переходит к другому потоку пула потоков (не потоку / владельцу BitmapSource).Этот код будет работать нормально без Task.Run (начальный переход к новому потоку).

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