为什么后台工作者会将报告进度保持在progresschanged事件中?

时间:2016-07-12 10:03:21

标签: c# .net winforms

DoWork活动中,我第一次下载所有电子邮件,并向ProgressChanged事件报告并更新listView(lvnf)。第二次完成下载所有电子邮件后,我再次点击该按钮,这次我在DoWork事件的每一行都添加了断点,它没有停在那里,但它不断更新listView ProgressChanged事件也使程序冻结一切都很慢。如何继续进入ProgressChanged事件并继续使用多个项目更新listView?我在ProgressChanged事件中添加了一个断点,它一直停在那里更新listView,但它永远不会停留在reportprogress行的DoWork事件中。我第二次点击按钮时正在谈论!它只在第一次下载所有电子邮件后第二次发生。

private void btnStart_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

Dowork活动:

private MimeKit.MimeMessage newmsg = null;
private HashSet<string> downloaded = new HashSet<string>();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        numberofallmessages = 0;
        using (var client = new Pop3Client())
        {
            client.Connect(textServer.Text, Convert.ToInt32(textPort.Text), ssl);
            client.AuthenticationMechanisms.Remove("XOAUTH2");
            client.Authenticate(textUser.Text, textPassword.Text);

            var uids = client.GetMessageUids();

            for (int i = 0; i < client.Count; i++)
            {
                if (backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                if (!downloaded.Contains(uids[i]))
                {
                    allMessages.Add(client.GetMessage(i));
                    newmsg = client.GetMessage(i);
                    downloaded.Add(uids[i]);
                    SaveFullMessage(client.GetMessage(i), i);
                    w = new StreamWriter(emailsIDSFile, true);
                    w.WriteLine(uids[i]);
                    w.Close();
                }
                int nProgress = (client.Count - i + 1) * 100 / client.Count;
                backgroundWorker1.ReportProgress(nProgress);
            }

            client.Disconnect(true);
        }
    }
    catch (Exception err)
    {
        string anyerrors = "";
    }
}

progresschanged事件

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pbt.Value = e.ProgressPercentage;
    pbt.Text = e.ProgressPercentage.ToString() + "%";
    pbt.Invalidate();
    if (newmsg != null)
    {
        ListViewCostumControl.lvnf.Items.Add(new ListViewItem(new string[]
    {
      newmsg.From.ToString(),         
      newmsg.Subject,                 
      newmsg.Date.ToString() 

    }));
    }
}

已完成的活动

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (closingForm)
        this.Close();
    label8.Text = numberofallmessages.ToString() + "/" + "0";
    downloadedallemailsfirsttime = true;
    countMsg = 0;
    FileInfo fi = new FileInfo(emailsIDSFile);
    if (fi.Length > 0)
    {
        downloadedallemailsfirsttime = true;
        lines = File.ReadAllLines(emailsIDSFile);
        for (int i = 0; i < lines.Length; i++)
        {
            seenUids.Add(lines[i]);
        }
    }
 }

我现在所做的并且似乎工作到目前为止是DoWork事件我发送newmsg作为报告进度的对象,并且newmsg { {1}}:

null

在进展改变的事件中:

private MimeKit.MimeMessage newmsg = null;
private HashSet<string> downloaded = new HashSet<string>();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        numberofallmessages = 0;
        countMsg = 0;
        using (var client = new Pop3Client())
        {
            client.Connect(textServer.Text, Convert.ToInt32(textPort.Text), ssl);
            client.AuthenticationMechanisms.Remove("XOAUTH2");
            client.Authenticate(textUser.Text, textPassword.Text);

            var uids = client.GetMessageUids();

            for (int i = 0; i < client.Count; i++)
            {
                if (backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                if (!downloaded.Contains(uids[i]))
                {
                    allMessages.Add(client.GetMessage(i));
                    newmsg = client.GetMessage(i);
                    downloaded.Add(uids[i]);
                    SaveFullMessage(client.GetMessage(i), i);
                    w = new StreamWriter(emailsIDSFile, true);
                    w.WriteLine(uids[i]);
                    w.Close();
                }

                int nProgress = (client.Count - i + 1) * 100 / client.Count;
                backgroundWorker1.ReportProgress(nProgress,newmsg);
                newmsg = null;
            }

            client.Disconnect(true);
        }
    }
    catch (Exception err)
    {
        string anyerrors = "";
    }
}

但即使它正在发挥作用,它仍然不是正确的答案。

1 个答案:

答案 0 :(得分:0)

您在private MimeKit.MimeMessage newmsgBackgroundWorker之间共享了一个backgroundWorker1_ProgressChanged。但backgroundWorker1_DoWork在循环中不断更改newmsg;当它更改newmsg时,旧值将被丢弃,backgroundWorker1_ProgressChanged将永远不会知道它是什么。您需要在循环的每次迭代中保存client.GetMessage(i)的值,并告诉backgroundWorker1_ProgressChanged每次迭代的内容。

首先,删除它:

private MimeKit.MimeMessage newmsg = null;

然后在backgroundWorker1_DoWork致电:

backgroundWorker1.ReportProgress(nProgress, client.GetMessage(i));

backgroundWorker1_ProgressChanged中你想要:

var newMsg = (MimeKit.MimeMessage)progressChangedEventArgs.UserState;
if (newMsg != null)
{
    ListViewCostumControl.lvnf.Items.Add(new ListViewItem(new string[]
    {
      newmsg.From.ToString(),         
      newmsg.Subject,                 
      newmsg.Date.ToString() 
    }));
}

修改:如果您要致电ReportProgress但要排除client.GetMessage(i)(如果已经报告),请将backgroundWorker1_DoWork更改为:

MimeKit.MimeMessage newmsg = null;
if (!downloaded.Contains(uids[i]))
{
    ...
    newmsg = client.GetMessage(i);
}

backgroundWorker1.ReportProgress(nProgress, newmsg );