关于BackgroundWorker的应用,我怎么用不好呢?

cxzy0930 2010-10-15 07:18:40

public void UpdateAllRSS()
{
if (this.tvRSS.Nodes != null && this.tvRSS.Nodes.Count > 0)
{
//tvRSS是TreeView控件
this.tvRSS.Nodes.Clear();
foreach (FeedBase feed in objProfileManager.objProfile.Feeds)
{
TreeNode node = tvRSS.Nodes.Add(feed.DisplayName);
feed.Articles.Clear();
feed.FetchArticles();
foreach (Article article in feed.Articles.Values)
{
node.Nodes.Add(article.Title);
}

}

}

}

上面这段是我更新RSS时耗时的地方,会导致UI假死,我想用BackgroundWorker显示进度条或显示假进度也行(只为了防UI假死),但是就是不会用,DoWork事件里一遇到TreeView就没了,也没有更新,不知道怎么回事?请问怎么配合ProgressBar啊?
...全文
166 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
cxzy0930 2010-10-16
  • 打赏
  • 举报
回复
结贴,ICanUseThisID ,感谢这位朋友,现在效果好很多了~
cxzy0930 2010-10-16
  • 打赏
  • 举报
回复
谢谢了,不知道为什么第一次启动程序,执行全更新时会卡,我再找一下原因吧,过一会结贴给你分~
cxzy0930 2010-10-16
  • 打赏
  • 举报
回复
谢谢了,不知道为什么第一次启动程序,执行全更新时会卡,我再找一下原因吧,过一会结贴给你分~
哥子谭 2010-10-16
  • 打赏
  • 举报
回复
其实使用BackgroundWorker不是很好,你可以尝试使用进度条控件
cxzy0930 2010-10-16
  • 打赏
  • 举报
回复
谢谢了,不知道为什么第一次启动程序,执行全更新时会卡,我再找一下原因吧,过一会结贴给你分~
cxzy0930 2010-10-16
  • 打赏
  • 举报
回复
谢谢了,不知道为什么第一次启动程序,执行全更新时会卡,我再找一下原因吧,过一会结贴给你分~
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复
具体的业务逻辑我不知道,你可以在程序里输出代码的执行时间,找到执行时间长的地方,这样可以逐步缩小问题的范围。

//例如
private void updateAllWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
System.Diagnostics.StopWatch sw=new System.Diagnostics.StopWatch();
sw.Start();
workerUpdateAllRSS(e.UserState as FeedBase);
sw.Stop();
System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds);//输出本次执行workerUpdateAllRSS方法的时间(单位为ms)
this.toolStripProgressBar1.Value = e.ProgressPercentage;
}
cxzy0930 2010-10-15
  • 打赏
  • 举报
回复

protected void workerUpdateAllRSS(FeedBase feed)
{
TreeNode node = tvRSS.Nodes.Add(feed.DisplayName);
feed.Articles.Clear();
feed.FetchArticles();
foreach (Article article in feed.Articles.Values)
{
node.Nodes.Add(article.Title);
}
}
public void InitializeBackgroundWorker()
{
this.toolStripProgressBar1.Visible = true;
this.toolStripProgressBar1.Value = 0;
this.tvRSS.Nodes.Clear();

updateAllWorker = new BackgroundWorker();
updateAllWorker.WorkerReportsProgress = true;
updateAllWorker.DoWork += new DoWorkEventHandler(updateAllWorker_DoWork);
updateAllWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updateAllWorker_RunWorkerCompleted);
updateAllWorker.ProgressChanged += new ProgressChangedEventHandler(updateAllWorker_ProgressChanged);
this.updateAllWorker.RunWorkerAsync();
}

private void updateAllWorker_DoWork(object sender, DoWorkEventArgs e)
{
progressUpdate((BackgroundWorker)sender);
}

private void updateAllWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
{
this.toolStripProgressBar1.Visible = false;
}
}

private void updateAllWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
workerUpdateAllRSS(e.UserState as FeedBase);
this.toolStripProgressBar1.Value = e.ProgressPercentage;
}

public void progressUpdate(BackgroundWorker worker)
{
List<FeedBase> argument = objProfileManager.objProfile.Feeds;
for (int i = 0; i < argument.Count; i++)
{
if (worker.CancellationPending)
{
break;
}
else
{
worker.ReportProgress(((i + 1) * 100) / argument.Count, argument[i]);
Thread.Sleep(800);
}
}

}


这样写可以吗?不过第一次全更新时为什么会卡一下呢?不是按进度一点一点长的,是先卡一会,再一下子长了好多, 第一次全更新后再全更新就会正常了,比如5个feed,就会一次长20%进度~~请教一下,我会加分的,谢谢了~
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复


//this是不是ui?
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.Text = e.ProgressPercentage.ToString();
}
cxzy0930 2010-10-15
  • 打赏
  • 举报
回复
那请问,不能直接操作UI的话,我的TreeView在哪里更新啊?进度怎么赋值??多谢了,实在不明白~
你的例子倒是简单,但我不明白我更新的那段代码该放在何处啊?
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复
DoWork在线程池中的某个线程执行,所以不能直接操作ui
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复
给你贴出例子了,怎么不仔细看呢
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);[Quote=引用 3 楼 cxzy0930 的回复:]

请问是不是BackgroundWorker的DoWork事件中不能调用UI控件啊?那我的那段代码怎么显示进度呢?
[/Quote]
cxzy0930 2010-10-15
  • 打赏
  • 举报
回复
请问是不是BackgroundWorker的DoWork事件中不能调用UI控件啊?那我的那段代码怎么显示进度呢?
ICanUseThisID 2010-10-15
  • 打赏
  • 举报
回复

//简单的一个例子
public partial class Form1 : Form
{
private BackgroundWorker worker;

public Form1()
{
InitializeComponent();

worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerAsync();
}

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.Text = e.ProgressPercentage.ToString();
}

void worker_DoWork(object sender, DoWorkEventArgs e)
{
int percent = 0;
while (true)
{
(sender as BackgroundWorker).ReportProgress(percent++);
if (percent >= 100)
{
percent = 0;
}

System.Threading.Thread.Sleep(100);
}
}
}

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧