你异步读取怎么这么麻烦啊,为什么不把ReportReadingProgress包装到一个现成里边呢?
要异步读的时候启动现成就可以了。你这样循环的启动异步线程会不会很浪费啊。class ReaderWrapper
{
   Thread readThread;
   ClsStateObject arg;
   private void ReportReadingProgress(IAsyncResult asyncResult){//这里面循环调用Stream.Read就行了,知道符合arg参数的要求为止}
   public ReaderWrapper(ClsStateObject obj)
   {
       arg = obj;
       readThread = new Thread(new ThreadState(ReportReadingProgress));
       readThread.Start();
   }}

解决方案 »

  1.   

    我真的很纳闷CSDN上的高手哪里去了????????
      

  2.   

    你是不是可以启动个新的thread执行dvd
      

  3.   

    >>Stream stream =fileobject.m_fs
    m_fs从未赋值,还是你代码没有贴全
    另:m_ProgressBar也没看到赋值的代码,所以。。把你所有代码帖出来看看不要在AsyncCallback里操作界面上的控件,如PROGRESSBAR等,更不用说MessageBox了,用Invoke,有可能就算抛了异常也弹不出来,造成没有执行的假象
      

  4.   

    给你个列子看看对你有没有用,我的这个是读取文本文件到网页中的
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.IO;namespace YXDS.ZCFG
    {
    /// <summary>
    /// index 的摘要说明。
    /// </summary>
    public class index : System.Web.UI.Page
    {
    const int pageSize = 19;
    private int currentPage = 0;
    private int pageCount = 0;
    private int recordCount;
    private int currentRecord=0;
    private string fileName;
    private string webNamelink;
    private string path;
    private string ImagePath;

    protected System.Web.UI.WebControls.TextBox TextBox1;
    protected System.Web.UI.WebControls.HyperLink linkUp;
    protected System.Web.UI.HtmlControls.HtmlForm Form1;
    protected System.Web.UI.WebControls.HyperLink HyperLink1;
    protected System.Web.UI.WebControls.Label title;
    protected System.Web.UI.WebControls.HyperLink linkBack;
    protected System.Web.UI.WebControls.Image Image1;
    protected System.Web.UI.WebControls.HyperLink linkNext;
    private void Page_Load(object sender, System.EventArgs e)
    {
    //获取文件名
    fileName = Request.QueryString["FileName"];
    webNamelink = Request.QueryString["webName"];
    path = Server.MapPath(fileName); if(!IsPostBack)
    {
    ImagePath = fileName;
    TextBox1.Text = BindPageDate();
    title.Text = GetFileName(fileName);
    Image1.ImageUrl = GetImagePath(ImagePath);
    }

    } #region Web 窗体设计器生成的代码
    override protected void OnInit(EventArgs e)
    {
    //
    // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
    //
    InitializeComponent();
    base.OnInit(e);
    }

    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {  
    this.Load += new System.EventHandler(this.Page_Load); }
    #endregion public string BindPageDate()
    {
    //用于将信息写入字符串的 TextWriter
    StringWriter strWriter = new StringWriter();
    //用流的方式输出
    Console.SetOut(strWriter);
    try 
    {
    if(Request.QueryString["currentRecord"]!=null)
    {
    currentPage = System.Int32.Parse(Request.QueryString["currentPage"]);
    pageCount = System.Int32.Parse(Request.QueryString["pageCount"]);
    currentRecord = System.Int32.Parse(Request.QueryString["currentRecord"]);
    webNamelink = Request.QueryString["webNamelink"];
    }
    else
    currentPage = 1;
    StreamReader strReader = new StreamReader(path,System.Text.Encoding.GetEncoding("GB2312"));
    //定义一数组用于存取当前页显示的内容
    ArrayList fileText = new ArrayList();
    strReader = File.OpenText(path);
    string str; //读取文件内容
    while ((str=strReader.ReadLine())!=null) 
    fileText.Add(str); recordCount=fileText.Count; //关闭流
    strReader.Close();
    //计算总页数
    if(!Page.IsPostBack)
    pageCount =(int)System.Math.Ceiling((double)recordCount/pageSize);
    //输出数组的值
    for(int i=currentRecord; i<(pageSize*currentPage)&&i<recordCount; i++)
    Console.WriteLine(fileText[i]); if(pageCount>=1)
    {
    }

    }
    //异常处理
    catch (Exception) 
    {
    Console.WriteLine("读取文件"+ fileName +" 时出错。请确保它在正确的目录中");

    }
    return strWriter.ToString();
    } public string GetFileName(string fileName)
    {

    } public string GetImagePath(string ImagePath)
    {

    }
    }
    }
      

  5.   

    楼上的对我没什么帮助的!不过非常感谢您!真不知道CSDN上的高手都到什么地方去了?
      

  6.   

    你的这个程序没有问题AsyncCallback可以引发自定义的Delegate,这样就可以通过事件通知Window Form完成窗体操作了。本身并没有idiotzeng(白痴) 说的那么可怕。
    你的程序的问题在于你并没有让主线程在完成所有任务之后退出,而是执行完代码就退出了。要让主线程等待其他现在执行的任务要使用手工事件来帮助设置代码执行的标记。我已经给你的代码添加上了这部分功能。以下是我该好的程序,你可以拷贝过去执行一下,看能否正常工作。using System;
    using System.IO;
    using System.Data;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    namespace EditDVDFile
    {
    /// <summary>
    /// ClsCompex 的摘要说明。
    /// </summary>
    public class ClsCompex
    {
    //我将你的回调函数定义改成了全局变量
    private AsyncCallback callBackMethod;
    //定义手工事件
    private ManualResetEvent m_hWait;
    public static int m_progressVal;
    public ClsCompex()
    {
    }

    public void DVDCompex(string filename,string DesPath)
    {
    //设置手工事件**************//给你新添加的
    m_hWait = new ManualResetEvent (false);
    //使用文件名来构造FileStream流
    FileStream fs =new FileStream(filename,FileMode.Open,FileAccess.Read, FileShare.Read,1,true);
    //构造ClsStateObject对象,并初始化其中的数据
    ClsStateObject fileobject=new ClsStateObject();
    fileobject.m_CurrentPos=0;
    fileobject.m_FileName=filename;
    fileobject.m_FileLength=fs.Length;
    //缓冲区长度规定为2000字节
    fileobject.m_BufferLength =2000;
    fileobject.m_ReadBuffer=new Byte[(int) fileobject.m_BufferLength];
    //构造回调方法
    callBackMethod =new AsyncCallback(ReportReadingProgress);
    //启动异步读取操作
    fs.BeginRead(fileobject.m_ReadBuffer,0,(int) fileobject.m_BufferLength,CallBackMethod,fileobject);
    //启动一部读取后,设置等待事件,
    //使主线程不至于提前退出,等待异步读取结束后再退出
    m_hWait.WaitOne();
    //等待所有任务结束后重置手工事件
    m_hWait.Reset();
    }

    public void ReportReadingProgress(IAsyncResult asyncResult)
    {
    try
    {
    ClsStateObject fileobject=(ClsStateObject)asyncResult.AsyncState;
    Stream stream =fileobject.m_fs;//new FileStream(fileobject.FileName,FileMode.Open);
    int byteRead=stream.EndRead(asyncResult);
    fileobject.m_CurrentPos+=byteRead;
    fileobject.m_ProgressBar.Value=(int) (fileobject.m_CurrentPos * fileobject.m_ProgressBar.Maximum /  fileobject.m_FileLength); if (fileobject.m_CurrentPos < fileobject.m_FileLength)
    {
    callBackMethod = new AsyncCallback(ReportReadingProgress);
    stream.BeginRead(fileobject.m_ReadBuffer,0,(int)fileobject.m_BufferLength,callBackMethod,fileobject);
    if (fileobject.m_ReadBuffer.Length>0)
    fileobject.m_fsw.Write (fileobject.m_ReadBuffer,0,(int)fileobject.m_BufferLength);
    else
    fileobject.m_fsw.Close();
    }
    else 
    {
    MessageBox.Show(fileobject.m_FileName +"读取结束","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
    m_hWait.Set();
    stream.Close();
    }
    }
    catch(Exception e)
    {
    MessageBox.Show(e.Message,"error");
    m_hWait.Set();
    }

    } }
    }
      

  7.   

    函数DVDCompex的退出代表程序的退出?
      

  8.   

    我的意思不是说"函数DVDCompex的退出代表程序的退出?",我想问问楼上在楼主的代码中和楼主所描述的情况来看函数DVDCompex是由主线程来执行的吧!如果你否认这一点,那么我也不多说了,你也没必要再看下去了!
          如果你承认这一点,那么我想问你,如果主线程在执行任务的时候,我设置一个标志,然后用异步方式去完成另外一个任务,当该标志没有被标记结束时主线程一直在标记开始处等待另外一个任务的完成,直到标记被设置为已完成。如果你不懂或者不明白,你可以查MSDN,你可以查异步调用是怎么回事儿,什么是异步调用,线程的控制等等内容,别忘了看ManualResetEvent类是干什么用的。
      

  9.   

    >>当该标志没有被标记结束时主线程一直在标记开始处等待另外一个任务的完成,直到标记被设置为已完成主线程因为WaitOne阻塞了,和直接调用Read有什么分别
      

  10.   

    你就是没有弄明白异步编程的意思,异步编程给你一种错觉,好像就是一个线程在执行任务,而实际上异步本上就会启动另外一个线程来完成一部处理的操作,这个操作并不是由主线程执行;在调用WaitOne以后主线程等待异步线程去完成任务,而主线程本身并没有因此而阻塞,这个等待就是告诉主线程当前任务没有完全结束,请你先不要结束这个函数调用,当标记被设置以后,异步线程会通知主线程该异步调用的任务已经完成。
         如果我说得不明白你可以查msdn,如果你的确是想知道一些东西,那你就应该自己摸索、体会而不是在这里和我磨嘴皮。真麻烦!