Co.*_*den 10 .net c# stored-procedures backgroundworker progress-bar
我有一个愚蠢的问题,但我被卡住了.我正在执行一个存储过程表单,我的代码过程需要时间,所以为此我显示一个进度条,显示执行的进度,但存储过程执行,没有任何东西,我增加进度条的值.
这是我的代码
void btnYes_Click(object sender, EventArgs e)
{
if (DialogResult.Yes == MessageBox.Show("Are you sure", "", MessageBoxButtons.YesNo))
{
try
{
dbDataEntities db = new dbDataEntities();
string myquery = "DECLARE @return_value int EXEC @return_value = [dbo].[ssspUpdateMarksOfStudent] SELECT 'Return Value' = @return_value";
//progressbar1.Maximum = 5000;
//progressbar1.value = ?; // how could i increment it
//
db.Database.ExecuteSqlCommand("myquery");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我尝试通过设置当前执行程序时没有增加的值来使用秒表
Stopwatch st = new Stopwatch();
st.Start();
progressbar1.Maximum = 5000;
progressbar1.Value = Convert.ToInt16(st.Elapsed.Seconds);
//My stored procedure call
st.Stop();
Run Code Online (Sandbox Code Playgroud)
所以它只能通过使用background worker或有任何其他方式来完成吗?
我是编程的新手所以没有太多使用background worker,所以我试图寻找替代方案.
请建议.提前致谢.
Erd*_*tur 11
一个有趣的想法SqlConnection提供了InfoMessage在服务器执行PRINT命令时触发的事件.您可以在存储过程的某些部分进行打印并收听此事件.
-- do something
PRINT '10 PERCENT COMPLETED';
-- do another thing
PRINT '20 PERCENT COMPLETED';
...
PRINT '100 PERCENT COMPLETED';
Run Code Online (Sandbox Code Playgroud)
除此之外,使用@ hamlet-hakobyan的解决方案.只是展示一个无限的进度吧.
首先,我讨厌给出完整的答案.它会妨碍大脑找到解决方案的能力.相反,我喜欢将人们推向正确的道路,这样他们就可以走路了.但无论如何它在这里.在W7x64SP1和SQL2012下使用VS2012,NET4,MSIL进行测试.
我非常耗时SP.用于RaisError代替Print立即发送消息.
Create Procedure usp_LongProcess As Begin
Declare @i Int;
Declare @msg VarChar(50);
Set @i = 0;
while (@i < 100) Begin
WaitFor Delay '00:00:02';
Set @i = @i + 10;
Set @msg = Convert(VarChar(10), @i) + ' PERCENT COMPLETE';
RaisError(@msg, 1, 1) With NoWait
End
End
Run Code Online (Sandbox Code Playgroud)
和我的形式
CallSpButton)progress)statusLabel)和SpCaller)与WorkerReportsProgress集true.
最后是拨打电话的代码
private void CallSpButton_Click(object sender, EventArgs e)
{
CallSpButton.Enabled = false;
SpCaller.RunWorkerAsync();
}
private void SpCaller_DoWork(object sender, DoWorkEventArgs e)
{
var self = (BackgroundWorker) sender;
var cb = new SqlConnectionStringBuilder
{
DataSource = ".",
InitialCatalog = "Sandbox",
IntegratedSecurity = true
};
using (var cn = new SqlConnection(cb.ToString()))
{
cn.FireInfoMessageEventOnUserErrors = true;
cn.Open();
cn.InfoMessage += (o, args) => self.ReportProgress(0, args.Message);
using (var cmd = cn.CreateCommand())
{
cmd.CommandText = "usp_LongProcess";
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
}
}
}
private void SpCaller_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CallSpButton.Enabled = true;
}
private void SpCaller_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var message = Convert.ToString(e.UserState);
Debug.WriteLine(message);
statusLabel.Text = message;
if (message.EndsWith(" PERCENT COMPLETE"))
{
int percent;
if (int.TryParse(message.Split(' ')[0], out percent))
progress.Value = percent;
}
}
Run Code Online (Sandbox Code Playgroud)
看起来你正在gui线程上运行存储过程.
这意味着当呼叫正在运行时,您的应用程序将无响应,因为消息泵已被阻止.这可能是一个坏主意.我建议将所有长时间运行的调用移动到另一个线程.
后台工作程序是一个旨在执行此操作的类,允许您报告长时间运行的任务是如何进行的,以便您可以更新UI,但由于您的任务只是一个项目,因此没有太多要报告的内容,因此它可能不是你的正确选择.
也许你想要一些形式(猜测语法,因为我没有编译器可以处理)并借用Windows Forms ProgressBar:最简单的方法来启动/停止选框?
progressbar1.Style = ProgressBarStyle.Marquee; //thanks Hamlet
progressbar1.MarqueeAnimationSpeed = 30;
//run the long running thing on a background thread.
var bgTask = Task.Factory.StartNew(() => db.Database.ExecuteSqlCommand("myquery"));
//when it's done, back on this thread, let me know and we'll turn the progress bar off
bgTask.ContinueWith(resultTask => {
progressBar1.Style = ProgressBarStyle.Continuous;
progressBar1.MarqueeAnimationSpeed = 0;
}, TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14001 次 |
| 最近记录: |