none
richTextBox异步加载txt文档错误

    问题

  • using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace 多线程异步加载
    {
        public partial class 异步 : Form
        {
            public 异步()
            {
                InitializeComponent();
            }
            public delegate void UpdateTxt(string msg);
            public void UpdateTxtMethod(string msg)
            {
                richTextBox1.AppendText(msg+"\n\r");
                richTextBox1.ScrollToCaret();
            }
            public UpdateTxt upd;
            public void ThreadMethodTxt()
            {
                string[] lines = System.IO.File.ReadAllLines(@"D:\TestTxtFileLoad.txt", Encoding.Default);
                for (int i = 0; i < lines.Length; i++)
                {
                    this.BeginInvoke(upd, lines[i]);
                }
            }
    
            private void 异步_Load(object sender, EventArgs e)
            {
                upd = new UpdateTxt(UpdateTxtMethod);
                Thread th = new Thread(new ThreadStart(ThreadMethodTxt));
                th.Start();
            }        
        }
    }

    this.BeginInvoke(upd, lines[i]);//报错

    上下文“0x1a2c28”已断开连接。正在从当前上下文(上下文 0x1a2ab8)释放接口。这可能会导致损坏或数据丢失。要避免此问题,请确保在应用程序全部完成 RuntimeCallableWrapper (表示其内部的 COM 组件)之前,所有上下文/单元都保持活动状态。

    2016年9月13日 2:57

答案

全部回复

  • 您用的读文件的方法 System.IO.File.ReadAllLines 不合适,要用Stream,可以有以下二个参考

    1 MSDN  https://msdn.microsoft.com/en-us/library/mt674879.aspx

    private async Task<string> ReadTextAsync(string filePath) { using (FileStream sourceStream = new FileStream(filePath,
            FileMode.Open, FileAccess.Read, FileShare.Read,
            bufferSize: 4096, useAsync: true))
        {
            StringBuilder sb = new StringBuilder();

            byte[] buffer = new byte[0x1000];
            int numRead;
            while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
            {
                string text = Encoding.Unicode.GetString(buffer, 0, numRead);
                sb.Append(text);
            }

            return sb.ToString();
        }
    }

    或是   https://blogs.msdn.microsoft.com/csharpfaq/2012/01/23/using-async-for-file-access/

    2 CodeProject

    http://www.codeproject.com/Articles/15181/Asynchronous-file-IO-using-anonymous-methods

    FileStream fs = new FileStream("C:\\sample.txt",FileMode.Open);

    fs.BeginRead(data,0,data.Length,delegate(IAsyncResult ar) { /* Section 1...some code*/ },null);


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年9月13日 6:17
  • 同步和异常的比较可以看这里

    http://stackoverflow.com/questions/18331349/c-sharp-4-5-file-read-performance-sync-vs-async

    结论是异步读取文件,在执行速度上并没有多少改善


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年9月13日 6:21
  • 我的VS2005不支持async关键字,载入txt文件代码本身是没有问题的,我把D:\TestTxtFileLoad.txt内容减小到500kb时是没有问题(原文件2.68MB)
    2016年9月14日 7:33
  • 异步载入只是一个测试,我想给载入加入一个进度条,加载大文件时以便清楚加载情况
    2016年9月14日 7:36
  • 升级.NET框架版本可以支持async关键字,.NET4.5

    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年9月14日 7:51
  • 努力了N天我的windows XP安装不了.Net Framework 4.5,你文件流分块加载效率远高于行读取,谢谢。
    2016年9月19日 1:35
  • 把richTextBox1.ScrollToCaret();注销掉就行了,这句没用。另外最好直接打开流读取。

    using System;
    using System.IO;
    using System.Threading;
    using System.Windows.Forms;
    namespace WindowsFormsApplication1
    {
    	public partial class Form1 : Form
    	{
    		public Form1()
    		{
    			InitializeComponent();
    		}
    		public delegate void UpdateTxt(string msg);
    		public void UpdateTxtMethod(string msg)
    		{
    			richTextBox1.AppendText(msg + "\n\r");
    			//richTextBox1.ScrollToCaret();
    		}
    		public UpdateTxt upd;
    		public void ThreadMethodTxt()
    		{
    			using (StreamReader sr = File.OpenText(@"D:\TestTxtFileLoad.txt"))
    			{
    				string s = "";
    				while ((s = sr.ReadLine()) != null)
    				{
    					this.BeginInvoke(upd, s);
    				}
    			}
    		}
    		private void OnLoaded(object sender, EventArgs e)
    		{
    			upd = new UpdateTxt(UpdateTxtMethod);
    			Thread th = new Thread(new ThreadStart(ThreadMethodTxt));
    			th.Start();
    		}
    	}
    }

    没有报错了,richTextBox1.ScrollToCaret();//将控件内容滚动至插入符位置,不清楚什么原因报错?能解释下吗

    2016年9月20日 2:41
  • richTextBox1.ScrollToCaret();

     使用ScrollToCaret()可以将滚动条定位到当前光标处
     richTextBox1.AppendText(DateTime.Now.Ticks.ToString()+Environment.NewLine);
     richTextBox1.ScrollToCaret();

     richtextbox 使用ScrollToCaret()可以将滚动条定位到当前光标处

    http://blog.csdn.net/keenweiwei/article/details/7305847

    或是看MSDN的解释

    https://msdn.microsoft.com/zh-cn/library/system.windows.forms.textboxbase.scrolltocaret%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年9月20日 6:28
  • ?????
    • 已标记为答案 倭黑猩猩 2016年9月21日 1:22
    • 已编辑 [-] 2018年1月11日 12:12
    2016年9月20日 9:09
  • 我注释richTextBox1.ScrollToCaret();报错消失了,根据提示我总感觉是我的窗体线程被挂起,后台异步线程却在修改窗体控件,具体原理上的原因我不清楚,不纠结了。感谢两位!
    2016年9月21日 1:22