首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VB Dotnet >

关于用多线程显示进度条的有关问题

2012-02-21 
关于用多线程显示进度条的问题我想通过程序进行数据库备份,同时开启一个线程用来显示进度条,代码如下。但是

关于用多线程显示进度条的问题
我想通过程序进行数据库备份,同时开启一个线程用来显示进度条,代码如下。但是当点击按钮进行数据库备份的时候,进度条无法正常显示进度,当数据库备份结束后才显示进度条的进度,清高人指点。
'点击备份按钮事件
  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线程池,更安全也更简单

热点排行