Я изучаю теги, чтобы улучшить производительность своих приложений и нахожусь в стороне от проблемы. Я хочу обновить пользовательский интерфейс из другого потока, из того, что я могу собрать, я должен использовать 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);
}
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()
и используйте функцию, так как она не изменена в этой функции. Надеюсь, это помогло очистить ваше понимание.
Идея DispatcherTimer
заключается в том, что вы запускаете ее в основном потоке, и она также запускается в основном потоке. Поэтому не создавайте нити, просто создавайте DispatcherTimer. Вам не понадобится Dispatcher.BeginInvoke()
, так как тик будет в основном потоке.