为什么我得到“无效的跨线程访问”;当使用Dispatcher.BeginInvoke()时
本文关键字:Dispatcher BeginInvoke 访问 无效 线程 为什么 | 更新日期: 2023-09-27 18:04:52
我正在寻找标题,以提高我的应用程序的性能,我碰到了一个问题。我想从另一个线程更新UI,从我可以收集我应该使用Dispatcher.BeginInvoke
为此,但当我运行下面的代码我得到一个关于无法访问其他线程的错误。什么好主意吗?
错误是An 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()
仅在您想要在主UI线程上发生的更改时使用,即在运行时修改UI,当有另一个线程(可能是主线程)正在进行时显示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()
,并使用function,因为该函数中没有修改ui。
DispatcherTimer
的想法是你在主线程中启动它,它也在主线程中触发。所以不要创建任何线程,只创建DispatcherTimer。您也不需要Dispatcher.BeginInvoke()
,因为tick将在主线程中。