C# Winforms后台工作程序卡住了

C# Winforms后台工作程序卡住了,c#,winforms,backgroundworker,C#,Winforms,Backgroundworker,我试图构建一个简单的代码,将csv文件连接到一个不同的文件中,但我的后台工作人员似乎有自己的想法,我的代码每次都会卡住。 以下是我使用后台工作程序加入文件的代码: private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { try { if (string.IsNullOrEmpty(saveFilePath)) {

我试图构建一个简单的代码,将csv文件连接到一个不同的文件中,但我的后台工作人员似乎有自己的想法,我的代码每次都会卡住。 以下是我使用后台工作程序加入文件的代码:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            if (string.IsNullOrEmpty(saveFilePath))
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    btnBrowseSave.PerformClick();
                }));
            }
            if (!string.IsNullOrEmpty(saveFilePath))
            {
                if (dragEventArgs != null)
                    files = (string[])dragEventArgs.Data.GetData(DataFormats.FileDrop);

                int filesCount = 0, rowsCount = 0;
                foreach (string file in files)
                {
                    filesCount++;
                    int fileTotalLines = File.ReadAllLines(file).Length;

                    this.Invoke(new MethodInvoker(delegate
                    {
                        lblFileName.Text = "Loading file: " + file.Substring(file.LastIndexOf("\\") + 1);
                        lblTotalFiles.Text = "File " + filesCount + " of " + files.Length;
                    }));

                    using (StreamReader reader = new StreamReader(file))
                    {
                        using (StreamWriter writer = new StreamWriter(saveFilePath))
                        {
                            while (!reader.EndOfStream)
                            {
                                try
                                {
                                    while (stopPosition > rowsCount)
                                    {
                                        reader.ReadLine();
                                        rowsCount++;
                                    }
                                    string email = reader.ReadLine().Trim();
                                    if (!string.IsNullOrEmpty(email) && !dicEmails.ContainsKey(email))
                                    {
                                        dicEmails.Add(email, null);
                                        writer.WriteLine(email);
                                    }
                                    rowsCount++;
                                    stopPosition++;

                                    backgroundWorker.ReportProgress((rowsCount * 100 / fileTotalLines), (int)ProgressType.Row);
                                    if (backgroundWorker.CancellationPending)
                                        return;
                                }
                                catch (Exception ex)
                                {
                                    hadReadErrors = true;
                                }
                            }
                        }
                    }
                    backgroundWorker.ReportProgress(0, (int)ProgressType.Row);
                    backgroundWorker.ReportProgress((filesCount * 100 / files.Length), (int)ProgressType.File);
                }
            }
        }
        catch (Exception ex)
        {
            hadReadErrors = true;
            MessageBox.Show(ex.Message);
        }
        finally
        {
            backgroundWorker.Dispose();
        }
    }

    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        try
        {
            switch ((int)e.UserState)
            {
                case (int)ProgressType.Row:
                    lblFileProgress.Text = e.ProgressPercentage + "%";
                    fileProgressBar.Value = e.ProgressPercentage;
                    break;
                case (int)ProgressType.File:
                    lblTotalProgress.Text = e.ProgressPercentage + "%";
                    totalProgressBar.Value = e.ProgressPercentage;
                    break;
            }
        }
        catch (Exception ex) { }
    }
当我在调试模式下运行并使用调试器时,我看不到任何问题,但当我让代码自行运行时,它会被卡住并崩溃。 谁能帮帮我,告诉我我错过了什么

例外情况如下:

Managed Debugging Assistant 'ContextSwitchDeadlock' has detected a problem in    
'C:\Users\Develop\Desktop\ExcelBuilder\ExcelBuilder\bin\Debug\ExcelBuilder.vshost.exe'.

Additional information: The CLR has been unable to transition from COM context 0x90fb78 
to COM context 0x90fc30 for 60 seconds. The thread that owns the destination
context/apartment is most likely either doing a non pumping wait or processing a very 
long running operation without pumping Windows messages. This situation generally has 
a negative performance impact and may even lead to the application becoming non 
responsive or memory usage accumulating continually over time. To avoid this problem, 
all single threaded apartment (STA) threads should use pumping wait primitives 
(such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

我做了一个你的程序的小例子,试图猜测它必须做什么(将4个文件拖放到groupbox,lorem?.csv),你应该考虑以下几点:

  • 永远不要尝试/捕获未知异常、每个异常或无法处理的事情()
  • 在窗体上使用BackgroundWorker时,请使用“sender”作为对它的引用,它是方法()的线程安全对象
  • 可能您更新表单的速度太快,请将Invoke方法更改为BeingInvoke,然后执行异步更新()
所以,只要修复它就可以运行它,如下所示:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker bckw = (BackgroundWorker)sender; // Recommended way, thread safe

    try
    {
        if (string.IsNullOrEmpty(saveFilePath))
        {
            this.Invoke(new MethodInvoker(delegate
            {
                btnBrowseSave.PerformClick();
            }));
        }
        if (!string.IsNullOrEmpty(saveFilePath))
        {
            if (dragEventArgs != null)
                files = (string[])dragEventArgs.Data.GetData(DataFormats.FileDrop);

            int filesCount = 0, rowsCount = 0;
            foreach (string file in files)
            {
                filesCount++;
                double fileTotalLines = File.ReadAllLines(file).Length;

                this.BeginInvoke(new MethodInvoker(delegate
                {
                    lblFileName.Text = "Loading file: " + file.Substring(file.LastIndexOf("\\") + 1);
                    lblTotalFiles.Text = "File " + filesCount + " of " + files.Length;
                })); // Invoke async, way too fast this...

                using (StreamReader reader = new StreamReader(file))
                {
                    using (StreamWriter writer = new StreamWriter(saveFilePath))
                    {
                        while (!reader.EndOfStream)
                        {
                            try
                            {
                                while (stopPosition > rowsCount)
                                {
                                    reader.ReadLine();
                                    rowsCount++;
                                } // why are you using that? it won't get TRUE

                                string email = reader.ReadLine().Trim();
                                if (!string.IsNullOrEmpty(email) && !dicEmails.ContainsKey(email))
                                {
                                    dicEmails.Add(email, null);
                                    writer.WriteLine(email);
                                }
                                rowsCount++;
                                stopPosition++;

                                bckw.ReportProgress((int)Math.Round(rowsCount * 100 / fileTotalLines, 0), (int)ProgressType.Row);
                                if (bckw.CancellationPending)
                                    return;
                            }
                            catch (Exception ex)
                            {
                                hadReadErrors = true;
                                throw; // Throw it again, or you won't know the Exception
                            }
                        }
                    }
                }
                bckw.ReportProgress(0, (int)ProgressType.Row);
                bckw.ReportProgress((filesCount * 100 / files.Length), (int)ProgressType.File);
            }
        }
    }
    catch (Exception ex)
    {
        hadReadErrors = true;
        MessageBox.Show(ex.Message);
    }
    finally
    {
        bckw.Dispose();
    }
}

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //try
    //{
    switch ((int)e.UserState)
    {
        case (int)ProgressType.Row:
            lblFileProgress.Text = e.ProgressPercentage + "%";
            if (e.ProgressPercentage <= fileProgressBar.Maximum)
                fileProgressBar.Value = e.ProgressPercentage;
            break;
        case (int)ProgressType.File:
            lblTotalProgress.Text = e.ProgressPercentage + "%";
            totalProgressBar.Value = e.ProgressPercentage;
            break;
    }
    //}
    //catch (Exception ex) { } // Don't catch everything
}
private void backgroundWorker\u DoWork(对象发送方,DoWorkEventArgs e)
{
BackgroundWorker bckw=(BackgroundWorker)发送方;//推荐方式,线程安全
尝试
{
if(string.IsNullOrEmpty(saveFilePath))
{
this.Invoke(新方法调用器(委托
{
btnBrowseSave.PerformClick();
}));
}
如果(!string.IsNullOrEmpty(saveFilePath))
{
if(dragEventArgs!=null)
files=(string[])dragEventArgs.Data.GetData(DataFormats.FileDrop);
int filescont=0,rowscont=0;
foreach(文件中的字符串文件)
{
filescout++;
double fileTotalLines=File.ReadAllLines(File).Length;
this.BeginInvoke(新方法调用程序(委托
{
lblFileName.Text=“正在加载文件:”+file.Substring(file.LastIndexOf(“\\”)+1);
lblTotalFiles.Text=“File”+filescont+”of“+files.Length;
}));//调用异步,速度太快了。。。
使用(StreamReader=新StreamReader(文件))
{
使用(StreamWriter writer=newstreamwriter(saveFilePath))
{
而(!reader.EndOfStream)
{
尝试
{
同时(停止位置>划船)
{
reader.ReadLine();
rowsCount++;
}//你为什么用这个?它不会变成真的
字符串email=reader.ReadLine().Trim();
如果(!string.IsNullOrEmpty(电子邮件)和&!dicEmails.ContainsKey(电子邮件))
{
添加(电子邮件,空);
writer.WriteLine(电子邮件);
}
rowsCount++;
停止位置++;
bckw.ReportProgress((int)Math.Round(rowscont*100/filetotalines,0),(int)ProgressType.Row);
如果(bckw.取消待定)
返回;
}
捕获(例外情况除外)
{
hadreaderors=true;
throw;//再次抛出它,否则您将不知道异常
}
}
}
}
bckw.ReportProgress(0,(int)ProgressType.Row);
bckw.ReportProgress((filescont*100/files.Length),(int)ProgressType.File);
}
}
}
捕获(例外情况除外)
{
hadreaderors=true;
MessageBox.Show(例如Message);
}
最后
{
bckw.Dispose();
}
}
private void backgroundWorker_ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
//试一试
//{
开关((int)e.UserState)
{
案例(int)ProgressType.Row:
lblFileProgress.Text=e.ProgressPercentage+“%”;

如果(e.ProgressPercentage什么异常?定义获取Stuck进度条不移动,主窗体没有响应。我在问题中添加了异常,因为它太长了。什么行崩溃,什么异常?我在上面的问题中添加了异常,因为它太长了有多少文件/行您可能正在使用进度更改淹没messagepump。请禁用每行报告,然后重试。非常感谢您的精彩回答:-)