在内存中读取文件,然后调用richtextbox [英] Read file in memory and then invoke a richtextbox

查看:86
本文介绍了在内存中读取文件,然后调用richtextbox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我遇到了一个棘手的问题:

Form1 =>添加了进度条

Form2 =>添加了后台工作者

在DoWork中,我想将文件读入内存,而不是将该文件发送到Form2的richtextbox中打开。



我收到一个错误:跨线程操作无效:从其创建的线程以外的线程访问Richtextbox



所以,我搜索谷歌,发现我需要调用rochtextbox ..



你能帮忙吗?

这是我的代码到现在为止:



  void  backgroundWorker1_DoWork( object  sender,DoWorkEventArgs e)
{

// 您的后台任务在这里
for int i = 0 ; i < = 100 ; i ++)
{
// 向'UI'线程报告进度
backgroundWorker1.ReportProgress(i);

string path = articles \\ + name + 。dat;
尝试
{
使用(FileStream fileStream = File.OpenRead (路径))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0 ,( int )fileStream.Length );
}
richTextBox1.Invoke( new MethodInvoker( delegate {name1 = richTextBox1。文字;}));
//
this .richTextBox1.LoadFile(path,RichTextBoxStreamType.RichText);
this .richTextBox1.ReadOnly = true ;
}
catch (例外ee)
{
Console.WriteLine(ee.Message);
}


}
}

解决方案

TPL是最简单:



任务<   FxMaintenanceChildViewModel  >  task = Task.Factory.StartNew <   strReturn  > ((stateObj)=> 
{
//在此处获取数据
返回strReturn;
},null);
task.ContinueWith(rtn =>
{
//将字符串放入
richTextBox1.Text = rtn;
},UiScheduler);


问题在于:

 。 richTextBox1.LoadFile(path,RichTextBoxStreamType.RichText); 
.richTextBox1.ReadOnly = true ;





这两行应该是通过 System.Windows.Forms.Control.Invoke 调用的方法。



您无法从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



此外,前两行没有任何意义。您调用的方法什么都不做,并且您将文件流的内容读取到内存流,这没有任何意义。你真的需要一个字符串分配给字符串属性 RichTextBox.Rtf ,所以你需要读取 char [] 缓冲区,将其转换为字符串并分配。



此外,整个活动与线程不会帮助你避免一些UI冻结多,因为大部分时间不会花在读取文件上,而是花在控件上的 Rtf 值上,因为应该更改。所以,实际上,最好通过UI线程中的控件本身读取RTF文件。



-SA

Luci C写道:

表单1是MDIParent,它显示的是Form2,它是一个mdichild。在Form2上我有一个链接 - >打开Form3,其中一些内容从文件中读取。

这是一个想法:谁需要MDI?为什么要折磨自己并吓跑你的用户?

帮自己一个大忙:根本不要使用MDI。没有它,您可以更轻松地实现设计,质量更好。 MDI甚至被微软高度劝阻,事实上,微软将其从WPF中删除并且很难支持它。更重要的是,如果您使用MDI,您将吓跑所有用户。只是不要。请参阅:

http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages [ ^ ],

如何在WPF中创建MDI父窗口? [ ^ ]。



我可以解释做什么。请看我过去的答案:

如何在WPF中创建MDI父窗口? [解决方案2 ],

关于在WPF中使用MDI窗口的问题 [ ^ ],

麦当劳给出错误 [ ^ ],

如何设置子窗体最大化,最后一个子窗体最小化 [ ^ ]。



-SA

So I am having a difficult problem:
Form1=> added a progress bar
Form2 => added a background worker
In the DoWork, I want to read a file into memory, than send that file to open in a richtextbox from Form2.

I am getting an error : "Cross-thread operation not valid: Richtextbox accessed from a thread other than the thread it was created on"

So, I searched google, and found put that I need to invoke the rochtextbox..

can you please help?
This is my code till now:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {

            // Your background task goes here
            for (int i = 0; i <= 100; i++)
            {
                // Report progress to 'UI' thread
                backgroundWorker1.ReportProgress(i);

                string path = "articles\\" + name + ".dat";
                try
                {
                    using (FileStream fileStream = File.OpenRead(path))
                    {
                        MemoryStream memStream = new MemoryStream();
                        memStream.SetLength(fileStream.Length);
                        fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
                    }
                    richTextBox1.Invoke(new MethodInvoker(delegate { name1 = richTextBox1.Text; }));
//
                    this.richTextBox1.LoadFile(path, RichTextBoxStreamType.RichText);
                    this.richTextBox1.ReadOnly = true;
                }
                catch (Exception ee)
                {
                    Console.WriteLine(ee.Message);
                }
  

            }
        }

解决方案

TPL is the easest:

Task<FxMaintenanceChildViewModel> task = Task.Factory.StartNew<strReturn>((stateObj) =>
    {
        // Get the data here
        return strReturn;
    }, null);
task.ContinueWith(rtn =>
    {
       //put string into 
       richTextBox1.Text = rtn;
    }, UiScheduler);


The problem is here:

this.richTextBox1.LoadFile(path, RichTextBoxStreamType.RichText);
this.richTextBox1.ReadOnly = true;



These two lines should be in a method invoked via System.Windows.Forms.Control.Invoke.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

Also, previous two lines make no sense. Your invoked method does nothing, and you read the content of the file stream to memory stream, which makes no sense. You really need a string to be assigned to the string property RichTextBox.Rtf, so you need to read to the char[] buffer, convert it to string and assign.

Besides, the whole activity with the thread won''t help you to avoid some UI freezing much, because most of the time will be spent not on reading of the file, but on the assignment of Rtf value to the control, as the changes should be rendered. So, practically, it would be better to read the RTF file by the control itself in the UI thread.

—SA


Luci C wrote:

Form 1 is MDIParent and it show up Form2 which is an mdichild. On the Form2 I have a link-> which opens Form3 with some content read from file.

Here is the idea: who needs MDI, ever? Why torturing yourself and scaring off your users?
Do yourself a great favor: do not use MDI at all. You can do much easier to implement design without it, with much better quality. MDI is highly discouraged even by Microsoft, in fact, Microsoft dropped it out of WPF and will hardly support it. More importantly, you will scare off all your users if you use MDI. Just don''t. Please see:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages[^],
How to Create MDI Parent Window in WPF?[^].

I can explain what to do instead. Please see my past answers:
How to Create MDI Parent Window in WPF? [Solution 2],
Question on using MDI windows in WPF[^],
MDIContainer giving error[^],
How to set child forms maximized, last childform minimized[^].

—SA


这篇关于在内存中读取文件,然后调用richtextbox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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