请大家看一下这段代码,为什么数据库可以备份成功,但不显示进度?网上查了都说可以显示,我的却不能。
#region 数据库的备份和实时进度显示
public bool BackupDB(string _strFileName)
{
m_tspbProgressBar.Value = 0;// 进度条
m_tspbProgressBar.Maximum = 100;
m_tspbProgressBar.Visible = true;
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass();
try
{
svr.LoginSecure = false;
svr.Connect(m_strServerName, m_strUserName, m_strPwd);
SQLDMO.Backup bak = new SQLDMO.BackupClass();
bak.Action = 0;
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step);
bak.PercentComplete += pceh;
bak.Files = _strFileName;
bak.Database = m_strDbName;
bak.Initialize = true;
bak.SQLBackup(svr);
return true;
}
catch (Exception err)
{
throw (new Exception(string.Format("备份数据库失败!\r\n错误信息:{0}", err.Message)));
}
finally
{
svr.DisConnect();
m_tspbProgressBar.Visible = false;
}
}
private void Step(string message, int percent)
{
m_tspbProgressBar.Value = percent;
Application.DoEvents();
}
#endregion
#region 数据库的备份和实时进度显示
public bool BackupDB(string _strFileName)
{
m_tspbProgressBar.Value = 0;// 进度条
m_tspbProgressBar.Maximum = 100;
m_tspbProgressBar.Visible = true;
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass();
try
{
svr.LoginSecure = false;
svr.Connect(m_strServerName, m_strUserName, m_strPwd);
SQLDMO.Backup bak = new SQLDMO.BackupClass();
bak.Action = 0;
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step);
bak.PercentComplete += pceh;
bak.Files = _strFileName;
bak.Database = m_strDbName;
bak.Initialize = true;
bak.SQLBackup(svr);
return true;
}
catch (Exception err)
{
throw (new Exception(string.Format("备份数据库失败!\r\n错误信息:{0}", err.Message)));
}
finally
{
svr.DisConnect();
m_tspbProgressBar.Visible = false;
}
}
private void Step(string message, int percent)
{
m_tspbProgressBar.Value = percent;
Application.DoEvents();
}
#endregion
你把代理,回调了本线程的函数,把UI给阻塞了。你可以试试 BackgroundWorker 组件。http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(VS.80).aspx
new 一个 Thread 是么? * V *
对,不过最简单的方法是用 backgroundworker组件
现在问题是 用MessageBox显示percent始终为0:
private void Step(string message, int percent)
{
m_tspbProgressBar.Value = percent;
Application.DoEvents();
MessageBox.Show(percent.ToString());// percent始终为0;
}
percent值为0则不可能带动进度条前进。
progressBar.Minimum = 0;
progressBar.Maximum = 100;
progressBar.BackColor = Color.Green;
for (int i = 0; i < ds.Tables["表"].Rows.Count; i++)
{
progressBar.Value++;
Application.DoEvents();
this.label1.Text = Convert.ToString(progressBar.Value);
}
参考
我不明白你为什么要用Messagebox,它的出现将阴塞主线程,倒不是说它始终为零,而是由于它出现了,使得整个过程被它中断了。你可以用其它的办法来显示,不是有一个 progressbar 控件么?用它来显示进度。
这样吧,你单步进去,看看每次该 Step 回调函数执行时,persent 的值是多少。如果没有变化的话,那么就应该是SQLDMO.BackupSink_PercentCompleteEventHandler这一代理的问题,而不是你的问题了。
Step(string message, int percent)函数的percent值始终为0,测试代码如下:
private void Step(string message, int percent)
{
//m_tspbProgressBar.Value = percent; // 因为percent值始终为0,进度条无法显示进度,
m_tspbProgressBar.Value += 10; // 这样却就可以显示进度,只是假进度条。
Label1.Text += percent.ToString(); // Label1标签显示结果为“0000000”,在窗口上可以实时的看到一个一个“0”被累加显示,证明percent值始终为0。
Application.DoEvents();
}
请各位不要再提醒我用BackgroundWorker组件,或说测试percent值方法不对。
毛主席说的“没有调查就没有发言权”!热心的朋友最好把这段代码复制到你的程序中运行,看是否有进度显示,解决后再指教,非常感谢!
注:是SQL Server 2005版本。
改成this.Text = percent.ToString(); 至于原因,较复杂,不赘述了。
这样做实在很难理解,备份执行完毕后this.Text="0" 即窗口标题为“0”。又有什么意义?
参考:http://tech.ddvip.com/2008-12/1229332510100151.html
而且测试percent值实时的显示在窗口标题上为“0000000000”,进度条当然也无法正确显示。
是不是因为是SQL Server 2005的原因呀?在线等待,如果谁解决了,马上给100分。
而且测试percent值实时的显示在窗口标题上为“0000000000”,进度条当然也无法正确显示。
是不是因为是SQL Server 2005的原因呀?在线等待,如果谁解决了,马上给100分。
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace dbBackUp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} string m_strServerName = string.Empty;
string m_strUserName = string.Empty;
string m_strPwd = string.Empty;
string m_strDbName = string.Empty; public void BackupDB(object FileName)
{
string _strFileName = FileName.ToString();
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass();
try
{
svr.LoginSecure = false;
svr.Connect(m_strServerName, m_strUserName, m_strPwd);
SQLDMO.Backup bak = new SQLDMO.BackupClass();
bak.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step);
bak.PercentComplete += pceh;
bak.Files = _strFileName;
bak.Database = m_strDbName;
bak.BackupSetName = m_strDbName;
bak.Initialize = true;
bak.SQLBackup(svr);
}
catch (Exception err)
{
throw (new Exception(string.Format("备份数据库失败!\r\n错误信息:{0}", err.Message)));
}
finally
{
svr.DisConnect();
}
} private void Step(string message, int percent)
{
m_tspbProgressBar.Value = percent;
Application.DoEvents();
} private void btnBackUp_Click(object sender, EventArgs e)
{
m_strServerName = txtServer.Text;
m_strUserName = txtUserId.Text;
m_strPwd = txtPwd.Text;
m_strDbName = txtDbName.Text;
string fileName = txtFile.Text;
m_tspbProgressBar.Value = 0;
m_tspbProgressBar.Minimum = 0;// 进度条
m_tspbProgressBar.Maximum = 100;
m_tspbProgressBar.Visible = true;
ParameterizedThreadStart ts = new ParameterizedThreadStart(BackupDB);
IAsyncResult result = this.BeginInvoke(ts, fileName); while (!result.IsCompleted)
{
Application.DoEvents();
} if (result.IsCompleted)
{
m_tspbProgressBar.Visible = false;
MessageBox.Show("备份成功","Message");
}
}
}
}
23楼iStarSoft你好!
我已测试,一样的不行。我的是VS2005+SQL Server 2005。不知道是不是SQL Server 2005的问题。
我是将你项目中的Form1加入到我项目中进行测试的,“//using System.Linq;不用”也可以运行。
后来我加入了测试代码:
private void Step(string message, int percent)
{
this.Text += percent.ToString();// 加入代码,让窗口标题显示进度结果
m_tspbProgressBar.Value = percent;
Application.DoEvents();
}
窗口标题显示结果为“Form10000000000”,进度条也没有反映,证明percent值为0。
下载这个http://www.brsbox.com/filebox/down/fc/dcc44f919b7a69dcc737b532614d303f运行下,
在VS2005 + SQL2005下测试通过,server\uid\pwd\dbname改成你自己的.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
//using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace Lb090
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} string m_strServerName = string.Empty;
string m_strUserName = string.Empty;
string m_strPwd = string.Empty;
string m_strDbName = string.Empty; public void BackupDB(object FileName)
{
string _strFileName = FileName.ToString();
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass();
try
{
svr.LoginSecure = false;
svr.Connect(m_strServerName, m_strUserName, m_strPwd);
SQLDMO.Backup bak = new SQLDMO.BackupClass();
bak.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step);
bak.PercentComplete += pceh;
bak.Files = _strFileName;
bak.Database = m_strDbName;
bak.BackupSetName = m_strDbName;
bak.Initialize = true;
bak.SQLBackup(svr);
}
catch (Exception err)
{
throw (new Exception(string.Format("备份数据库失败!\r\n错误信息:{0}", err.Message)));
}
finally
{
svr.DisConnect();
}
} private void Step(string message, int percent)
{
this.Text += percent.ToString();// 加入测试代码,让窗口标题显示进度结果
m_tspbProgressBar.Value = percent;
Application.DoEvents();
} private void btnBackUp_Click(object sender, EventArgs e)
{
m_strServerName = txtServer.Text;
m_strUserName = txtUserId.Text;
m_strPwd = txtPwd.Text;
m_strDbName = txtDbName.Text;
string fileName = txtFile.Text;
m_tspbProgressBar.Value = 0;
m_tspbProgressBar.Minimum = 0;// 进度条
m_tspbProgressBar.Maximum = 100;
m_tspbProgressBar.Visible = true;
ParameterizedThreadStart ts = new ParameterizedThreadStart(BackupDB);
IAsyncResult result = this.BeginInvoke(ts, fileName); while (!result.IsCompleted)
{
Application.DoEvents();
} if (result.IsCompleted)
{
MessageBox.Show("备份成功","Message");
m_tspbProgressBar.Visible = false;
}
}
}
}
我的是Windows server 2003服务器,难道是这个原因?
我的环境是XP+VS2005+sql 2005 EXPRESS,都是测试通过的.
我的环境是Windows Server 2003+VS2005+SQL Server 2005。
有谁能够真正解决呀?请指教。
{
m_tspbProgressBar.Value = percent; // 理论上要改成委托,不过我试过了即使是委托也不会更新
Application.DoEvents(); //不用 } 最后我只好加个间隔为500毫秒的Timer过变通了,效果很好,
一个项目里写好的全段例子,无关的我都注释掉了, #region void TmiBackup_Click(object sender, EventArgs e) // 备份
/// <summary>
/// 备份
/// </summary>
/// <param name="sender">按钮本身</param>
/// <param name="e">按钮参数</param>
void TmiBackup_Click(object sender, EventArgs e)
{
// if (TvServerDirectories.SelectedNode == null || TvServerDirectories.SelectedNode.Text == DataBaseHost)
// return;
// frmBackupFileName BackupFileName = new frmBackupFileName();
// BackupFileName.FileName = DateTime.Now.ToString(Consts.DATETIME_FILELONGFORMAT);
// if (BackupFileName.ShowDialog() != DialogResult.OK)
// return;
// if (BackupFileName.FileName.Trim() == String.Empty)
// return;
// CurrentDirectory = TvServerDirectories.SelectedNode.Tag.ToString();
// CurrentFileName = BackupFileName.FileName.Trim() + "."
//+ Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_DATAFILE_EXT;
// if (MessageBox.Show(Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_CONFIRM(CurrentDirectory + CurrentFileName),
//String.Empty,
// MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
// return;
// TvServerDirectories.Enabled = false;
// ((ToolStripButton)TmiRefresh.Tag).Enabled = false;
// ((ToolStripButton)TmiBackup.Tag).Enabled = false;
// EdtBackupFiles.Enabled = false;
// MoBackupFileInfo.Enabled = false;
// MC.SlBackup.Text = Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_START;
// MC.TspLoading.Value = 0;
// MC.TspLoading.Maximum = 100;
// MC.TspLoading.Visible = true;
ProgressBarValue = 0;
Timer.Enabled = true;
BackupThread = new Thread(new ThreadStart(DoBackup));
BackupThread.IsBackground = true;
BackupThread.Start();
// HelpAgentControl.DoAction(new Consts.SERVICE_HELPAGENT_ACTION_PROCESSING(), false);
}
#endregion #region void DoBackup() // 备份线程
/// <summary>
/// 备份线程
/// </summary>
void DoBackup()
{
// DM 为通用委托方法类
Backup BackupDatabase = null;
SQLServer BackupDatabaseConnection = null;
try
{
// IsBackuping = true;
// HelpAgentControl.DoAction(new Consts.SERVICE_HELPAGENT_ACTION_PROCESSING(), false);
BackupDatabase = new BackupClass();
BackupDatabaseConnection = new SQLServerClass();
BackupDatabaseConnection.LoginSecure = false;
BackupDatabaseConnection.Connect(DataBaseHost, UserID, Password);
BackupDatabase.Action = SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
BackupDatabase.Database = DataBase;
String FullFileName = "[" + CurrentDirectory + CurrentFileName + "]";
BackupDatabase.Files = @" " + FullFileName;
BackupDatabase.BackupSetName = DataBase;
BackupDatabase.BackupSetDescription = CurrentFileName;
BackupDatabase.Initialize = true;
BackupSink_PercentCompleteEventHandler BackupDatabaseProgress = new BackupSink_PercentCompleteEventHandler(SetPercent);
BackupDatabase.PercentComplete += BackupDatabaseProgress;
BackupDatabase.SQLBackup(BackupDatabaseConnection);
// DM.SetTextSafely(MC.SlBackup, Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_END);
}
catch (Exception e)
{
// DM.SetTextSafely(MC.SlBackup, Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_ERROR(e.Message));
// DM.SetHintTextSafely(MC.SlBackup, Consts.SERVICE_MONITOR_BACKUPRESTORE_BACKUP_ERROR(e.Message));
}
finally
{
// IsBackuping = false;
// HelpAgentControl.DoAction(new Consts.SERVICE_HELPAGENT_ACTION_RESETPOSE(), false);
// BackupDatabaseConnection.DisConnect();
// DM.SetEnabledSafely(TvServerDirectories, true);
// DM.SetEnabledSafely(TmiRefresh.Tag, true);
// DM.SetEnabledSafely(TmiBackup.Tag, true);
// DM.SetEnabledSafely(EdtBackupFiles, true);
// DM.SetEnabledSafely(MoBackupFileInfo, true);
// DM.SetVisibleSafely(MC.TspLoading, false);
}
}
#endregion #region void SetPercent(String Message, int Percent) // 设置进度条进度值
/// <summary>
/// 设置进度条进度值
/// </summary>
/// <param name="Message">消息</param>
/// <param name="Percent">进度值</param>
void SetPercent(String Message, int Percent)
{
ProgressBarValue = Percent;
}
#endregion #region void Timer_Tick(object sender, EventArgs e) // 设置进度条进度
/// <summary>
/// 设置进度条进度
/// </summary>
/// <param name="sender">控件本身</param>
/// <param name="e">控件参数</param>
void timer_Tick(object sender, EventArgs e)
{
MC.TspLoading.Maximum = 100;
MC.TspLoading.Value = ProgressBarValue;
if (MC.TspLoading.Value >= MC.TspLoading.Maximum)
{
MC.TspLoading.Visible = false;
Timer.Enabled = false;
}
}
#endregion
我就奇怪,为什么完全一模一样的程序,在别人的XP系统里percent值不为0,而复制到我的WIN2003系统里percent值就始终为0,数据库却备份成功。
实在是不明白。有谁可以解开这个迷?谢谢!
我曾经做过一个数据转移的winform,其中的进度条是根据各步骤存储过程返回值控制线程委托回调
用多线程纯属是让进度条走的看起来比较真实,用不用都可以