i have a wpf form and a canvas in it and an image in canvas. i want this image to move randomly to directions every n milliseconds. i used while loop but it stocked in starvation. so i had no way to implement this movement by one mouse event to see how good is my idea about this movement. this is my code below:
public void movebox()
{
Random rnd = new Random();
int movex = rnd.Next(0, 2);
int movey = rnd.Next(0, 2);
Canvas.SetTop(image1, Canvas.GetTop(image1) + (movey == 1 ? 1 : -1));
Canvas.SetLeft(image1, Canvas.GetLeft(image1) + (movex == 1 ? 1 : -1));
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
movebox();
}
i likes movement of image but now i have same problem yet. i need this object to move automatically forever every n milliseconds without starvation. this is my ideal code below:
while(true){
Random rnd = new Random();
int movex = rnd.Next(0, 2);
int movey = rnd.Next(0, 2);
Canvas.SetTop(image1, Canvas.GetTop(image1) + (movey == 1 ? 1 : -1));
Canvas.SetLeft(image1, Canvas.GetLeft(image1) + (movex == 1 ? 1 : -1));
Thread.Sleep(1000);
}
what should i have do now?
One thing you can do if you really want a loop is to start another thread and use that. This way your UI will stay responsive.
public void movebox()
{
Task.Run(() =>
{
while(true)
{
Random rnd = new Random();
int movex = rnd.Next(0, 2);
int movey = rnd.Next(0, 2);
Dispatcher.Invoke(() => {
Canvas.SetTop(image1, Canvas.GetTop(image1) + (movey == 1 ? 1 : -1));
Canvas.SetLeft(image1, Canvas.GetLeft(image1) + (movex == 1 ? 1 : -1));
});
Thread.Sleep(1000);
}
});
}
A better approach however is to use Timer
like this:
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
Random rnd = new Random();
int movex = rnd.Next(0, 2);
int movey = rnd.Next(0, 2);
Canvas.SetTop(image1, Canvas.GetTop(image1) + (movey == 1 ? 1 : -1));
Canvas.SetLeft(image1, Canvas.GetLeft(image1) + (movex == 1 ? 1 : -1));
}
Disclaimer: I have written the code in browser.