我想同步我的本地和Web数据库,所以我使用链接服务器编写了一个存储过程。我的存储过程执行正常,数据同步成功但过程大约需要7-10分钟才能执行。确切的时间无法确定。因此,只要程序在我的Windows应用程序上运行,那么该页面似乎已经变得没有响应,尽管该过程仍在继续。 所以我点击我的页面上有一个“数据同步”按钮,我希望进度条显示存储过程的进度。目前,我采用最后几个执行时序的平均值来定义存储过程运行的持续时间。现在的问题是,当我点击数据同步按钮时,进度条不起作用。请帮我解决这个问题。
我的代码如下: -
namespace RMS
{
public partial class DataSync : Form
{
connection con = new connection();
SqlCommand cmd = new SqlCommand();
static int rowCount;
static int syncTime;
static int timeSlice;
public DataSync()
{
InitializeComponent();
}
private void btnDataSync_Click(object sender, EventArgs e)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
try
{
con.GetConnectLive();
con.GetConnect();
if (con.CnLive.State == ConnectionState.Open)
{
MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");
btnDataSync.Enabled = false;
btnDataSync.Text = "Please Wait...";
string Str = "RMS_LocalToLive";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
rowCount = cmd.ExecuteNonQuery();
if (rowCount > -1)
{
MessageBox.Show("Total no. of rows synchronised = " + rowCount);
btnDataSync.Text = "Success";
}
else
{
MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
}
}
else
{
MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
}
con.GetDisConnect();
con.GetDisConnectLive();
}
catch (Exception ex)
{
MessageBox.Show("Please check your internet connection and try again!!!");
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
con.GetConnect();
string Str = "RMS_DataSyncTime";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
syncTime = Convert.ToInt32(cmd.ExecuteScalar().ToString());
timeSlice = syncTime / 100;
con.GetDisConnect();
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrieve last Data Synchronisation Timing");
}
for (int i = 1; i <= synctime; i=i+timeslice)
{
Thread.Sleep(timeslice);
// Report progress.
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Change the value of the ProgressBar to the BackgroundWorker progress.
progressBar1.Value = e.ProgressPercentage;
// Set the text.
this.Text = e.ProgressPercentage.ToString() + "% Completed";
}
private void DataSync_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgse)
{
}
}
}
答案 0 :(得分:0)
这里的主要问题是,当您在BackgroundWorker
的线程中执行进度条更新时,ReportProgress()
更新永远不会进入UI线程,因为您&# 39;用主SQL操作阻止了该线程。
而不是这样做,你应该做更多这样的事情:
private void btnDataSync_Click(object sender, EventArgs e)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
btnDataSync.Enabled = false;
btnDataSync.Text = "Please Wait...";
bool success = false;
try
{
// Execute the query asynchronously
success = await Task.Run(() => ExecuteLocalToLive());
}
catch (Exception ex)
{
MessageBox.Show("Please check your internet connection and try again!!!");
}
btnDataSync.Enabled = true;
btnDataSync.Text = success ? "Success" : "Failure";
}
private bool ExecuteLocalToLive()
{
bool success = false;
con.GetConnectLive();
con.GetConnect();
if (con.CnLive.State == ConnectionState.Open)
{
MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");
string Str = "RMS_LocalToLive";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
rowCount = cmd.ExecuteNonQuery();
if (rowCount > -1)
{
MessageBox.Show("Total no. of rows synchronised = " + rowCount);
success = true;
}
else
{
MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
}
}
else
{
MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
}
con.GetDisConnect();
con.GetDisConnectLive();
return success;
}
我重新安排了处理按钮状态和文本的代码,以便它仍然在它所属的UI线程中执行,即使方法本身不是。您似乎也从未将按钮设置回启用状态;我不清楚这是否是故意的,所以我继续前进并增加了一条线来做到这一点。
最后,我强烈建议您找出向用户报告状态的更好方法,而不是现在对MessageBox.Show()
的调用。最大的问题是,在用户解除初始消息之后,您甚至不会开始做任何工作,这会立即使您的进度条与实际工作不同步。但是,最好将所有UI保留在UI线程中,并将UI与非UI逻辑(即SQL操作)分开。