Reputation: 618
I am looking into theading to improve my apps performance and am hitting abit of an issue. i am wanting to update the UI from another thread, from what i can gather i should be using Dispatcher.BeginInvoke
for this however when i run the below code i get an error about not being able to access the other thread. any ideas?
The error is An Unhandled exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll
Additional information: Invalid cross-thread access."
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);
}
Upvotes: 1
Views: 1044
Reputation: 1560
Dispatcher.BeginInvoke()
is used only if you are doing changes which you want to happen on main UI thread i.e. modifying UI at run-time as showing ProgressBar when there is another thread (may be main thread) is going on.
Call DoSomething
directly without using any thread. Also, call SetUiData
directly but modify function like this:
private void SetUiData()
{
double NewTop = Convert.ToDouble(NewPlaneTop - PlaneFlight);
Dispatcher.BeginInvoke(() =>
PlaneObj.Margin = new Thickness(newPlaneLeft, NewTop, newPlaneRight, newPlaneBottom);
}
}
And finally call GetUiData
directly without Dispatcher.BeginInvoke()
and use function as it is as no ui is modified in that function. Hope this helped to clear your understanding.
Upvotes: 2
Reputation: 31143
The idea of the DispatcherTimer
is that you start it in the main thread and it fires in the main thread also. So don't create any threads, just create the DispatcherTimer. You won't need Dispatcher.BeginInvoke()
either, since the tick will be in the main thread.
Upvotes: 0