【问题标题】:How do i use backgroundworker with timer and progressBar?如何将 backgroundworker 与计时器和进度条一起使用?
【发布时间】:2014-07-30 18:33:01
【问题描述】:

我有一个计时器滴答事件,它的间隔设置为 10000

private void timer1_Tick(object sender, EventArgs e)
{
    Update();
}

在更新中我有:

public int Update()
{
    counter += 1;
    int position = (int)Math.Round((counter / updateTime) * 100);
    xpProgressBar1.Text = counter.ToString() + " %";
    xpProgressBar1.Position = counter;
    if (counter == 10)
    {
        DownloadingHtml();
        ScrollNews();
        counter = 0;
    }
    return position;
}

然后在后台worker做工作:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    int position = NewsUpdate();
    object param = "report";
    backgroundWorker1.ReportProgress(position, param);
}

还有backgroundworker进度事件:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

    xpProgressBar1.Text = e.ProgressPercentage.ToString() + " %";
    xpProgressBar1.Position = e.ProgressPercentage;
    if (counter == 10)
    {
        DownloadingHtml();
        ScrollNews();
        counter = 0;
    }
}

我想要在第一步中做的是每 10 秒调用一次更新方法,但通过后台工作程序。

在第二步中,我想向后台工作人员添加另一种方法:

public void ScrollNews()
{
    label3.Text = SaveOldHtml.HtmlLoadedFileNumber.ToString();
    richTextBox1.Clear();
    combindedString = string.Join(Environment.NewLine, ListsExtractions.myList);
    richTextBox1.SelectAll();
    richTextBox1.SelectionAlignment = HorizontalAlignment.Right;
    richTextBox1.Text = combindedString;
    scrollerText = string.Join(Environment.NewLine, ListsExtractions.myListWithoutLinks);
    scroller1.TextToScroll = scrollerText;
    if (NewsLevels.newsLevel && NewsLevels.shouldStart)
    {
        scroller1.Start();
        NewsLevels.shouldStart = false;
    }
    if (NewsLevels.newsLevel == false && NewsLevels.shouldStart)
    {
        scroller1.Start();
        NewsLevels.shouldStart = false;
    }
    string[] rlines = richTextBox1.Lines;
    richTextBox1.SelectionStart = 0;
    richTextBox1.SelectionLength = rlines[0].Length;
    richTextBox1.SelectionColor = Color.Red;
    richTextBox1.Select(rlines[0].Length, rlines[1].Length + 1);
    richTextBox1.SelectionColor = Color.Green;
}

ScrollNews 方法正在从 Update 方法中调用,它正在使用文本更新 RichTextBox1 和 Scroller1。

最后我想在更新中添加最后一个方法:

private void DownloadingHtml()
{           
    using (var webClient = new WebClient())
    {
        webClient.Encoding = System.Text.Encoding.GetEncoding(1255);
        page = webClient.DownloadString("http://rotter.net/scoopscache.html");
    }            
    StreamWriter w = new StreamWriter(@"d:\rotterhtml\rotterscoops.html");
    w.Write(page);
    w.Close();
    page = @"d:\rotterhtml\rotterscoops.html";
    listsext.Ext(page);
    count++;
}

所有这些方法我都想从后台工作人员那里工作。

在 form1 构造函数中,我首先执行此操作,它会调用一次 DownloadingHtml 方法,然后调用一次 ScrollNews 方法,然后激活后台工作程序,然后启动 timer1。

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    您似乎在滥用BackgroundWorker 类。它通常用于执行不应阻塞 UI 的单个耗时操作。所有耗时的操作都应在OnDoWork 事件中进行,该事件在单独的线程上执行。报告进度在 UI 线程上执行,用于更新进度条和其他显示进度的 UI 元素。

    timer1_Tick 在 UI 线程上执行,并在执行时阻塞您的 UI。如果您不希望 UI 挂起,那么在此处执行任何下载或处理都不是一个好主意。 您可以启动 TPL TaskThread 或在每次执行 timer1_Tick 时重新启动 BackgroundWorker。然后TaskThread 可以报告进度并更新当前 UI 状态,调用表单的线程安全方法。 BackgroundWorker 可以为此使用它自己的ReportProgress 机制。

    在使用单独的Task或Thread的情况下,从单独的线程调用的每个方法都应该检查Form的InvokeRequired并调用BeginInvoke来执行线程安全的UI更新。这在此处得到了很好的描述:beginInvoke, GUI and thread 和许多其他类似的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      相关资源
      最近更新 更多