Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 我如何处理一个;动画";在我的Windows窗体上不锁定UI?_Vb.net_Multithreading_Visual Studio - Fatal编程技术网

Vb.net 我如何处理一个;动画";在我的Windows窗体上不锁定UI?

Vb.net 我如何处理一个;动画";在我的Windows窗体上不锁定UI?,vb.net,multithreading,visual-studio,Vb.net,Multithreading,Visual Studio,我目前正在使用vb.net中的一些基本动画来改进终端客户端的GUI。这是一个很薄的面板条,当输入文本框时,它会在文本框下方循环延伸 它工作得很好。我的问题是,动画必须在文本框接受文本之前完成。这意味着,当用户在“用户名”和“密码”文本框之间进行制表时,他们有时会开始键入太快,动画无法完成,因此会错过密码的前几个字符 我曾尝试将“动画”代码添加到后台工作线程中,但当在两个文本框之间进行切换时,UI会完全冻结约20秒(单击时效果很好,但切换会导致工作线程冻结) 我做了一些研究,尽管有建议,但我不确定

我目前正在使用vb.net中的一些基本动画来改进终端客户端的GUI。这是一个很薄的面板条,当输入文本框时,它会在文本框下方循环延伸

它工作得很好。我的问题是,动画必须在文本框接受文本之前完成。这意味着,当用户在“用户名”和“密码”文本框之间进行制表时,他们有时会开始键入太快,动画无法完成,因此会错过密码的前几个字符

我曾尝试将“动画”代码添加到后台工作线程中,但当在两个文本框之间进行切换时,UI会完全冻结约20秒(单击时效果很好,但切换会导致工作线程冻结)

我做了一些研究,尽管有建议,但我不确定后台工作人员是否能在这种情况下工作,因为最终,它只会更新UI控件,而这似乎是后台工作人员要做的事情

这是我如何设置的:

Private Sub bwUsernameLines_DoWork(sender As Object, e As DoWorkEventArgs) Handles bwUsernameLines.DoWork
        Dim x As Integer = 0

        pnlUsername_under.Width = x
        pnlUsername_under.Visible = True

        'loop speed 1
        Do Until x = 180
            pnlUsername_under.Width = x
            Threading.Thread.Sleep(5)
            pnlUsername_under.Refresh()
            x += 10
        Loop

        bwUsernameLines.CancelAsync()
End Sub

Private Sub txtUsername_Enter(sender As Object, e As EventArgs) Handles txtUsername.Enter
        bwUsernameLines.RunWorkerAsync()
        txtUsername.Text = vbNullString
End Sub
在文本框中单击会导致UI冻结,而在文本框中单击则不会。是我做错了什么事情让它工作,还是有完全不同的方法


基本上,我只想让循环动画继续播放,而文本框允许输入文本,而不是等待它完成。

首先要做的是更改处理面板大小的位置。如果您已经正确理解,从非UI线程更改UI对象是有问题的,创建BackgroundWorker是为了解决WinForms应用程序中的此问题

因此,我们需要在BackgroundWorker上设置一些内容,以便为其任务做好准备。
(您可以通过Winform Designer或表单构造函数中的代码进行这些更改,但必须在InitializeComponent之后)

现在你的嫁妆可以改成

Private Sub bwUsernameLines_DoWork(sender As Object, e As DoWorkEventArgs) 
    Dim x As Integer = 0
    'loop speed 1
    Do Until x = 500
        Threading.Thread.Sleep(5)

        ' Raises the Progress_Changed event in the UI thread
        ' Notice that this overload takes an value that represent your progress so far
        bwUsernameLines.ReportProgress(x)
        x += 10
    Loop
End Sub
最后,只需为Progress\u Changed事件添加事件处理程序

Private Sub bwUsernameLines_SizeChanged(sender As Object, e As ProgressChangedEventArgs)
   ' Get that x passed above from the property  ProgressPercentage
   pnlUsername_under.Width = e.ProgressPercentage

End Sub 

您不应该在DoWork处理程序中更新UI。有一个ReportProgress方法,当调用该方法时会引发ProgressChanged事件,该处理程序在UI ThreadThank@Steve中运行-我假设DoWork处理程序不用于UI更新,但不太确定。你能详细说明我如何在上面实现它吗?它甚至不可能从后台线程/后台工作线程触摸UI,因为它应该抛出一个
invalidoOperationException
。您是否碰巧在代码中的任何地方设置了
Control.CheckForIllegalCrossThreadCalls=False
?如果是这样的话,你需要移除它,因为你已经禁用了一些重要的保护措施,这些保护措施可以阻止你做坏事。是的@VisualVincent-你找到我了。。。我确实关闭了它以允许应用程序调用UI线程。我遵循了一个糟糕的教程,其中提到了这一点。不过,我似乎不知道如何在UI中使用后台工作人员。好吧,既然后台工作人员不打算在UI中工作,你会发现有点困难也就不足为奇了。在任何两个线程之间封送调用或同步数据都很困难,因为它们彼此独立运行,因此容易出现争用情况。当涉及到多线程时,您应该努力使线程尽可能彼此分离。NET Framework确实为我们提供了许多不同的方法来同步线程,当您需要线程在某个时刻进行通信时。感谢@Steve-我已经在中添加了此方法,然后将Enter事件处理程序设置为RunWorkerAsync,但其结果与上一个设置相同-它单击并保持良好,但文本框之间的切换会使UI冻结约20秒。很抱歉,我无法重现此问题。我已经用LinqPad编写的代码测试了这种方法,没有任何延迟。有没有可能这里有什么不同的东西在起作用呢。我建议您编写一个测试代码,在右边的选项卡中只包含两个文本框,以便查看您是否能够在当前代码旁边重现您的问题。
Private Sub bwUsernameLines_SizeChanged(sender As Object, e As ProgressChangedEventArgs)
   ' Get that x passed above from the property  ProgressPercentage
   pnlUsername_under.Width = e.ProgressPercentage

End Sub