【发布时间】:2012-10-16 14:42:26
【问题描述】:
我有一个后台工作人员,负责处理我的应用程序中的计时器。这是代码:
protected override void OnLoad(EventArgs e)
{
// Inizializzo il backgroundworker
bgwTimer.WorkerReportsProgress = true;
bgwTimer.WorkerSupportsCancellation = true;
bgwTimer.DoWork += (bgwTimer_DoWork);
bgwTimer.RunWorkerCompleted +=(bgwTimer_RunWorkerCompleted);
bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged);
}
void bgwTimer_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
throw new NotImplementedException();
}
void bgwTimer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
throw new NotImplementedException();
}
基本上,“ProgressChanged”事件永远不会被触发,因此我无法更新进度条的状态。 事件 DoWork 与此方法相关联:
void bgwTimer_DoWork(object sender, DoWorkEventArgs e)
{
int i = 0;
if (bgwTimer.CancellationPending)
{
e.Cancel = true;
}
else
{
while (bgwTimer.IsBusy)
{
Thread.Sleep(1000);
bgwTimer.ReportProgress(i);
refreshTimer();
}
}
}
在我这边,代码看起来不错,运行良好。如您所见,调用了 ReportProgress 方法,但未触发事件。有什么提示吗?
更新: 哎呀!我发现只有在事件声明后立即运行 RunWorkerAsync 时才会触发事件“bgwTimer_ProgressChanged”。基本上:
bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged); bgwTimer.RunWorkerAsync(); //这行得通!
由于我在用户按下按钮时运行工作程序,因此不会触发事件。
点击事件按钮的代码如下:
private void btnNext_Click(object sender, EventArgs e)
{
this.TopMost = true;
btnNext.Enabled = false;
progressBar1.Step = 0;
if (_bgwTimer.IsBusy)
_bgwTimer.CancelAsync();
else
_bgwTimer.RunWorkerAsync();
}
【问题讨论】:
-
你没有增加 i 的值 - 也许这就是没有引发事件的原因?
-
一个可能有帮助的参考资料(虽然我找不到你的问题)在这里:albahari.com/threading/part3.aspx#_BackgroundWorker
-
罗伯特,定时器基本上是更新一个标签的Text属性,没有别的。
-
这可能是个问题。根据我发布的链接,您只应该更新 BGW 不在的某些线程中的 UI 元素,因此首先是 ProgressChanged 事件,这有助于解决这个问题。我想知道这种行为是否会导致其他“有趣”的行为?
-
在您的编辑中,您说使用按钮触发它时它不起作用。你睡眠处理按钮点击事件的线程吗?如果是这样,你已经暂停了 UI 线程(坏的),没有其他东西可以通过。哎呀,您的“完成”方法
bgwTimer_RunWorkerCompleted也不会运行。请发布您原来的“按钮点击事件”方法。我认为这将揭示根本原因。
标签: c# multithreading timer progress-bar backgroundworker