关于用多线程显示进度条的问题
我想通过程序进行数据库备份,同时开启一个线程用来显示进度条,代码如下。但是当点击按钮进行数据库备份的时候,进度条无法正常显示进度,当数据库备份结束后才显示进度条的进度,清高人指点。
'点击备份按钮事件
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Control.CheckForIllegalCrossThreadCalls = False
th = New Threading.Thread(New Threading.ThreadStart(AddressOf Me.progress))
Dim num As Long = 0
Me.Enabled = False
Me.ProgressBar1.Maximum = 100
Me.ProgressBar1.Minimum = 0
Me.ProgressBar1.Step = 10
Me.ProgressBar1.Value = 0
th.Start()
save()
bFinished = 1
End Sub
'显示进度条
Private Sub progress()
While Me.bFinished <> 1
If ProgressBar1.Value = 100 Then
Me.ProgressBar1.Value = 0
End If
ProgressBar1.Value += 10
Threading.Thread.Sleep(200)
Application.DoEvents()
End While
End Sub
'备份数据库
Private Sub save()
Dim datacomm As New DataComm
datacomm.data_connect()
Dim params() As SqlParameter = {New SqlParameter("@flag", SqlDbType.NVarChar), _
New SqlParameter("@backup_db_name", SqlDbType.NVarChar), _
New SqlParameter("@filename", SqlDbType.NVarChar)}
params(0).Value = "OK"
params(1).Value = "lh_pacs"
params(2).Value = "D:\data\lh_pacs" + CStr(Now.Date)
Directory.CreateDirectory("D:\data")
datacomm.data_executeSP("lh_backup_db", params)
'创建CIniAccess类的对象以书写配置文件和对字符串的加密
Dim oIni As New CIniAccess
'声明变量sPath记录配置文件的路径和文件名
Dim sPath As String = My.Application.Info.DirectoryPath + "\server1.ini"
'服务器IP
Dim server_ip As String = oIni.DecryptDes(oIni.INIRead(sPath, "单机版主机IP", "serverIP"), "12345678", "88888888")
'pacs的版本,如果isServer为“”或“true”,表示单机版;如果isServer为“false”,表示网络版;
Dim isServer As String = oIni.INIRead(sPath, "版本", "isServer")
If isServer = "false" Then '当前版本为网络版
MsgBox("您已经成功备份数据库至" + "\\" + server_ip + "\" + params(2).Value, , "提示!!")
ElseIf isServer = "" Or isServer = "true" Then '当前版本为单机版
MsgBox("您已经成功备份数据库至" + params(2).Value, , "提示!!")
End If
End Sub
[解决办法]
帮你顶
[解决办法]
While Me.bFinished <> 1
If ProgressBar1.Value = 100 Then
Me.ProgressBar1.Value = 0
End If
ProgressBar1.Value += 10
Threading.Thread.Sleep(200)
Application.DoEvents()
End While
如果bFinished不等于1,下面对进度条的操作都不会执行,所以出现“进度条无法正常显示进度,当数据库备份结束后才显示进度条的进度”
因为没有用过进度条,随意说说可以修改的方法。错了误怪:
去掉WHIle条件的判断,在设置了bFinished = 1的地方,停止th线程,设置进度条满格
[解决办法]
严重关注中!
------解决方案--------------------
只能搞个假的进度条,用线程同步进行显示控制
[解决办法]
MARK
[解决办法]
这个速度不是你自己能控制的,可以考虑学习一下服务的进度条控制。前50%的进度是每秒显示一个,然后用更多的时间显示下一个进度,直到你的备份完成为止。
[解决办法]
这么多代码,没时间看,关键给你个想法,供你参考下
[解决办法]
测试了一下(C#),你的代码没有问题
Thread t;
private void button2_Click(object sender, EventArgs e)
{
t = new Thread(new ThreadStart(Start));
t.Start();
}
bool b = true;
private void Start()
{
int i = 0;
while (b)
{
if (i > 100)
i = 0;
progressBar1.Value = i;
Thread.Sleep(200);
Application.DoEvents();
i += 10;
}
}
[解决办法]
你的代码逻辑不太合理,save()函数在宿主线程内执行,这样会消耗掉大量的CPU时间,应用程序根本没有办法去处理窗口重绘的工作,标准的逻辑是由辅助线程执行save()这样需要消耗大量时间和IO资源的函数,在save()函数内部通过委托更新进度条(当然你的代码中由于存在Control.CheckForIllegalCrossThreadCalls = False ,可以不用委托直接更新,但是这样不安全),最后建议你尽量不要使用new thread,改用threadpool线程池,更安全也更简单