你异步读取怎么这么麻烦啊,为什么不把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();
}}
要异步读的时候启动现成就可以了。你这样循环的启动异步线程会不会很浪费啊。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();
}}
m_fs从未赋值,还是你代码没有贴全
另:m_ProgressBar也没看到赋值的代码,所以。。把你所有代码帖出来看看不要在AsyncCallback里操作界面上的控件,如PROGRESSBAR等,更不用说MessageBox了,用Invoke,有可能就算抛了异常也弹不出来,造成没有执行的假象
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)
{
}
}
}
你的程序的问题在于你并没有让主线程在完成所有任务之后退出,而是执行完代码就退出了。要让主线程等待其他现在执行的任务要使用手工事件来帮助设置代码执行的标记。我已经给你的代码添加上了这部分功能。以下是我该好的程序,你可以拷贝过去执行一下,看能否正常工作。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();
}
} }
}
如果你承认这一点,那么我想问你,如果主线程在执行任务的时候,我设置一个标志,然后用异步方式去完成另外一个任务,当该标志没有被标记结束时主线程一直在标记开始处等待另外一个任务的完成,直到标记被设置为已完成。如果你不懂或者不明白,你可以查MSDN,你可以查异步调用是怎么回事儿,什么是异步调用,线程的控制等等内容,别忘了看ManualResetEvent类是干什么用的。
如果我说得不明白你可以查msdn,如果你的确是想知道一些东西,那你就应该自己摸索、体会而不是在这里和我磨嘴皮。真麻烦!