BeginInvoke的原因应用程序挂起在BackgroundWorker的 [英] BeginInvoke cause application hang in BackgroundWorker

查看:153
本文介绍了BeginInvoke的原因应用程序挂起在BackgroundWorker的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决这个问题的<一个href=\"http://stackoverflow.com/questions/18113513/read-the-huge-text-file-in-chunks-by-chunks-by-scollbar\">Question但我最后不得不另外一个问题结果
在简短的词汇这个问题是问如何用大块,结果一个巨大的文件加载到textBox中块
所以在回地面工人Do_work事件我这样做:

I was trying to solve the problem in this Question but I ended up having another problem
in short words that question was asking how to load a huge file into textBox chunk by chunk,
so in back ground worker Do_work event I did this:

using (FileStream fs = new FileStream(@"myFilePath.txt", FileMode.Open, FileAccess.Read))
{
    int bufferSize = 50;
    byte[] c = null;        
    while (fs.Length - fs.Position > 0)
    {
        c = new byte[bufferSize];
        fs.Read(c , 0,c.Length);                    
        richTextBox1.AppendText(new string(UnicodeEncoding.ASCII.GetChars(c)));
    }                
}        

这没有工作,因为一个BackgroundWorker可以在不影响用户界面元素和我需要使用的BeginInvoke做到这一点。

that didn't work because a backgroundWorker can't affect UI elements and I need to use BeginInvoke to do it.

所以我改变了code:

so I changed the code:

delegate void AddTextInvoker();

public void AddText()
{            
    using (FileStream fs = new FileStream(@"myFilePath.txt", FileMode.Open, FileAccess.Read))
    {
        int bufferSize = 50; 
        byte[] c = null;            
        while (fs.Length - fs.Position > 0)
        {
            c = new byte[bufferSize];
            fs.Read(c , 0,c.Length);                    
            richTextBox1.AppendText(new string(UnicodeEncoding.ASCII.GetChars(c)));
        }                
     }           
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    this.BeginInvoke(new AddTextInvoker(AddText));
}

有两个问题code。结果
1 - 它需要更长的时间和更长的时间文本(我想是因为字符串不变性的替换文本随着时间的推移将需要更长的时间)结果追加
2 - 每除了在RichTextBox会向下滚动到引起应用程序挂起结束。

there are two problems with this code.
1- it's taking longer and longer time to append the text (I think because of string immutability replacing the text over time will take longer)
2- on every addition the richTextBox will scroll down to the end which causing application hang.

问题是我能做些什么来阻止滚动和应用程序挂起?结果
而我能做些什么来提升这里字符串连接?

the question is what can I do to stop the scrolling and application hang?
and what can I do to enhance string concatenation here?

修改:在一些测试,并使用马特的答案,我得到这个:

Edit: after some testing and using Matt's answer I got this:

public void AddText()
{            
    using (FileStream fs = new FileStream(@"myFilePath.txt", FileMode.Open, FileAccess.Read))
    {
        int bufferSize = 50; 
        byte[] c = null;             
        while (fs.Length - fs.Position > 0)
        {
           c = new byte[bufferSize];
           fs.Read(c , 0,c.Length);

           string newText = new string(UnicodeEncoding.ASCII.GetChars(c));
           this.BeginInvoke((Action)(() => richTextBox1.AppendText(newText)));

           Thread.Sleep(5000); // here 
         }                
     }        
 }

当加载停顿我能读,没有问题或悬挂写,一旦文本超出了RichTextBox的大小将装载向下滚动,将prevent我从继续。

when the loading pauses I can read and write without problems or hanging, once the text exceeded the the richTextBox size the loading will scroll down and will prevent me from continue.

推荐答案

一个问题,我看到的是,你的背景工人,好了,不这样做在后台的任何工作。它在UI线程上运行的。这可能是为什么UI线程无响应。

One problem I see is that your background worker is, well, not doing any work in the background. It's all running on the UI thread. This may be why the UI thread is non-responsive.

我要细化DoWork的处理,像这样:

I would refine your DoWork handler like so:

public void AddText()
{            
    using (FileStream fs = new FileStream(@"myFilePath.txt", 
                   FileMode.Open, FileAccess.Read))
    {
        int bufferSize = 50; 
        byte[] c = null;            
        while (fs.Length - fs.Position > 0)
        {
            c = new byte[bufferSize];
            fs.Read(c , 0,c.Length);

            string newText = new string(UnicodeEncoding.ASCII.GetChars(c));
            this.BeginInvoke((Action)(() => richTextBox1.AppendText(newText));
        }                
     }           
}

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    AddText();
}

我所做的是局部使用的BeginInvoke 以在处理程序作出的单一用户界面调用。这样一来,所有的其他工作在后台线程完成。也许这将有助于UI线程变成无响应。

What I've done is localized the use of BeginInvoke to the single UI call made in the handler. That way, all of the other work is done in the background thread. Maybe that will help with the UI thread becoming non-responsive.

这篇关于BeginInvoke的原因应用程序挂起在BackgroundWorker的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆