Почему при использовании Dispatcher.BeginInvoke () я получаю «Неверный доступ к нескольким потокам»?

1

Я изучаю теги, чтобы улучшить производительность своих приложений и нахожусь в стороне от проблемы. Я хочу обновить пользовательский интерфейс из другого потока, из того, что я могу собрать, я должен использовать Dispatcher.BeginInvoke для этого, однако, когда я запускаю приведенный ниже код, я получаю сообщение об отсутствии возможности доступа к другому потоку. есть идеи?

Ошибка: Unhandled exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll

Дополнительная информация: Недопустимый сквозной доступ ".

public void StartPlaneThread()
    {
        var thread = new System.Threading.Thread(DoSomething);
        thread.Start();
    }

    private void DoSomething()
    {

        DispatcherTimer TimerTask;
        TimerTask = new DispatcherTimer();
        TimerTask.Tick += new EventHandler(NewPlaneMovement);
        TimerTask.Interval = new TimeSpan(0, 0, 0, 0, 10);
        TimerTask.Start();

    }

    int NewPlaneTop;
    int newPlaneBottom;
    int newPlaneLeft;
    int newPlaneRight;

    private void NewPlaneMovement(object sender, EventArgs e)
    {

        Dispatcher.BeginInvoke(() =>
            GetUiData() );

        Dispatcher.BeginInvoke(() =>
            SetUiData());






        PlaneFlight = PlaneFlight - 1;

        if (PlaneFlight < -10)
        {
            PlaneFlight = -10;
        }
    }

    private void SetUiData()
    {
        double NewTop = Convert.ToDouble(NewPlaneTop - PlaneFlight);
        PlaneObj.Margin = new Thickness(newPlaneLeft, NewTop, newPlaneRight, newPlaneBottom);
    }

    private void GetUiData()
    {
        NewPlaneTop = Convert.ToInt32(PlaneObj.Margin.Top);
        newPlaneBottom = Convert.ToInt32(PlaneObj.Margin.Bottom);
        newPlaneLeft = Convert.ToInt32(PlaneObj.Margin.Left);
        newPlaneRight = Convert.ToInt32(PlaneObj.Margin.Right);
    }
Теги:
multithreading
dispatcher
windows-phone-8

2 ответа

2

Dispatcher.BeginInvoke() используется только в том случае, если вы делаете изменения, которые должны произойти в основном потоке пользовательского интерфейса, то есть изменяя интерфейс во время выполнения, показывая ProgressBar, когда происходит еще один поток (может быть основной поток).

Вызовите DoSomething напрямую, не используя нить. Кроме того, вызовите SetUiData напрямую, но измените функцию следующим образом:

private void SetUiData()
{
    double NewTop = Convert.ToDouble(NewPlaneTop - PlaneFlight);
    Dispatcher.BeginInvoke(() =>
        PlaneObj.Margin = new Thickness(newPlaneLeft, NewTop, newPlaneRight, newPlaneBottom);
    }
}

И, наконец, вызовите GetUiData напрямую без Dispatcher.BeginInvoke() и используйте функцию, так как она не изменена в этой функции. Надеюсь, это помогло очистить ваше понимание.

0

Идея DispatcherTimer заключается в том, что вы запускаете ее в основном потоке, и она также запускается в основном потоке. Поэтому не создавайте нити, просто создавайте DispatcherTimer. Вам не понадобится Dispatcher.BeginInvoke(), так как тик будет в основном потоке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню