for (int i = 0; i < 100,000; i++)
{
threadEvent.Invoke(i, new EventArgs());// tell processbar value
}
threadEvent += new EventHandler(method_threadEvent);
void method_threadEvent(object sender, EventArgs e)
{
int nowValue = Convert.ToInt32(sender);
nowValueDelegate now = new nowValueDelegate(setNow);
this.Invoke(now, nowValue);
}
private void setNow(int nowValue)
{
this.progressBar1.Value = nowValue;
}
private delegate void nowValueDelegate(int nowValue);
循环中我什么都不做,但也浪费了很多时间!
为什么线程Event.Invoke花了这么多时间?
答案 0 :(得分:0)
调用是一项昂贵的操作,因为它必须跨越线程边界。
最好减少调用量,例如,只更新每个工作百分比的进度条,而不是循环的每次迭代。这样,只需要处理100个更新,而不是每次迭代都有一个。
您需要做的第一件事是计算或估计当前进度。 对于典型的循环
for (int i = 0; i < someValue; ++i)
{
... // Work here
}
对进度的良好估计是(i / someValue) * 100
,它给出了已经完成的循环的百分比。要仅在达到下一个百分比时更新UI线程的进度,您可以执行以下操作:
int percentCompleted = 0;
threadEvent.Invoke(percentCompleted, new EventArgs()); // Initial progressbar value
for (int i = 0; i < someValue; ++i)
{
int newlyCompleted = (i / someValue) * 100;
if (newlyCompleted > percentCompleted)
threadEvent.Invoke(percentCompleted, new EventArgs());
percentCompleted = newlyCompleted;
... // Work here
}
现在最后,您可以使用BeginInvoke而不是Invoke来确保工作线程不会等待threadEvent完成(PostMessage
行为)。这在这里工作得很好,因为你需要的threadEvent没有返回值。