C# 多线程窗体和用户控制

C# 多线程窗体和用户控制,c#,multithreading,C#,Multithreading,我的visual studio项目设置如下所示: 在窗体的面板上,我添加了用户控件(UC),代码如下: 以形式: panel.Controls.Add(UC.Instance); UC.Instance.Location = new Point(-(panel.Size.Width), 0); UC.Instance.BringToFront(); roll_in(); private static UC _instance; public static UC Instance { g

我的visual studio项目设置如下所示: 在窗体的面板上,我添加了用户控件(UC),代码如下:

形式

panel.Controls.Add(UC.Instance);
UC.Instance.Location = new Point(-(panel.Size.Width), 0);
UC.Instance.BringToFront();
roll_in();
private static UC _instance;
public static UC Instance
{
    get
    {
        if (_instance == null)
            _instance = new UC();
        return _instance;
    }
}
用户控件中

panel.Controls.Add(UC.Instance);
UC.Instance.Location = new Point(-(panel.Size.Width), 0);
UC.Instance.BringToFront();
roll_in();
private static UC _instance;
public static UC Instance
{
    get
    {
        if (_instance == null)
            _instance = new UC();
        return _instance;
    }
}
当我按下窗体上的按钮时,用户控件将添加到窗体的面板中,我使用以下代码将用户控件滑动到其位置:

private void roll_in()
{
    while (UC.Instance.Location.X < panel.Location.X)
    {
        UC.Instance.Location = new Point((UC.Instance.Location.X + 2));
        UC.Instance.Refresh();
        if (UC.Instance.Location.X > -10)
            System.Threading.Thread.Sleep(10);
    }
}
private void roll_in()
{
while(UC.Instance.Location.X-10)
系统线程线程睡眠(10);
}
}
当我使用
roll_in()
时,所有其他函数和表单都在等待此过程完成

有没有办法在另一个线程上滑动
用户控件
? 我试图通过创建另一个线程调用
roll\u in()
,但它说控件是在另一个线程上创建的

有人能帮我指引我走上正确的道路吗? 如何在不影响其他控件的情况下执行“动画”


感谢您的帮助

在我看来,您通过调用thread.sleep阻止了UI线程。你通常不想出于任何原因那样做。创建异步任务是为了处理这样的UI问题。试试这个代码

private async void roll_in()
{
    while (UC.Instance.Location.X < panel.Location.X)
    {
        UC.Instance.Location = new Point((UC.Instance.Location.X + 2));
        UC.Instance.Refresh();
        if (UC.Instance.Location.X > -10)
            await Task.Delay(10);
    }
}
private async void roll_in()
{
while(UC.Instance.Location.X-10)
等待任务。延迟(10);
}
}

这应该可以防止在睡眠周期中阻塞。

您还可以在循环中使用
Application.DoEvents()
定期处理winforms事件队列:

private void roll_in()
{
    while (UC.Instance.Location.X < panel.Location.X)
    {
        UC.Instance.Location = new Point((UC.Instance.Location.X + 2));
        UC.Instance.Refresh();
        Application.DoEvents();
}
private void roll_in()
{
while(UC.Instance.Location.X
}


有关
Application.DoEvents()

Winforms+Animations=wpfa的信息,我将从中构建一个Animator类,其中包含一个计时器来处理动画。Animator.AnimateLocation(控件:myControl,新位置:新点(x,y),持续时间:TimeSpan.FromSeconds(2))这似乎是一个简单的解决方案!我包括WinFormAnimation库来制作动画!但是感谢您提供的解决方案,我尝试了DoEvents()并且效果非常好!有办法增加延迟吗?@NikoLeben你想延迟什么?调用
DoEvents()
?UC.instance.location.x+2之间的延迟,因此面板移动速度将较慢。在这种情况下,涉及
async/await
的hack解决方案()和使用
Application.DoEvents()
的组合应该可以达到您所需的效果。只需将
Application.DoEvents()
调用放在
wait
调用之前或之后