我正在寻找改善我的应用程序性能的方法,并且正在努力解决问题。我想要从另一个线程更新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);
}
答案 0 :(得分:2)
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()
并使用函数,因为在该函数中没有修改ui。希望这有助于清除您的理解。
答案 1 :(得分:0)
DispatcherTimer
的想法是你在主线程中启动它,它也在主线程中触发。所以不要创建任何线程,只需创建DispatcherTimer。您也不需要Dispatcher.BeginInvoke()
,因为勾号将位于主线程中。