在 wpf 中实现无饥饿重绘图像的 while 循环
implement while loop without starvation for redrawing an image in wpf
我有一个 wpf 表单和一个 canvas,在 canvas 中有一个图像。我希望此图像每 n 毫秒随机移动到一个方向。我使用了 while 循环,但它处于饥饿状态。所以我没有办法通过一个鼠标事件来实现这个动作,看看我对这个动作的想法有多好。这是我的代码:
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();
}
我喜欢图像的移动,但现在我遇到了同样的问题。我需要这个物体每 n 毫秒自动移动一次而不会饿死。下面是我理想的代码:
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);
}
我现在应该做什么?
如果你真的想要一个循环,你可以做的一件事是启动另一个线程并使用它。这样您的 UI 就会保持响应。
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);
}
});
}
不过,更好的方法是像这样使用 Timer
:
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));
}
免责声明:我在浏览器中编写了代码。
我有一个 wpf 表单和一个 canvas,在 canvas 中有一个图像。我希望此图像每 n 毫秒随机移动到一个方向。我使用了 while 循环,但它处于饥饿状态。所以我没有办法通过一个鼠标事件来实现这个动作,看看我对这个动作的想法有多好。这是我的代码:
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();
}
我喜欢图像的移动,但现在我遇到了同样的问题。我需要这个物体每 n 毫秒自动移动一次而不会饿死。下面是我理想的代码:
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);
}
我现在应该做什么?
如果你真的想要一个循环,你可以做的一件事是启动另一个线程并使用它。这样您的 UI 就会保持响应。
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);
}
});
}
不过,更好的方法是像这样使用 Timer
:
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));
}
免责声明:我在浏览器中编写了代码。