首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# FileStream BeginRead 异步怎么取消

2012-04-15 
C# FileStream BeginRead 异步如何取消读取类大概如下:privateFileStream _filestreamprivate int _partS

C# FileStream BeginRead 异步如何取消
读取类大概如下:
private FileStream _filestream;
  private int _partSize = 1024 * 20;  

  private void Create(string fileName)
  {
  _filestream = new FileStream(
  fileName,
  FileMode.Open,
  FileAccess.Read,
  FileShare.Read,
  _partSize * 10,
  true);
   
   
  }

  public void Read(int index)
  {
  int size = _partSize;
   
  byte[] buffer = new byte[size];  
  ReadFileObject obj = new ReadFileObject(index, buffer);
  //...其它操作

  _filestream.BeginRead(
  buffer,
  0,
  size,
  new AsyncCallback(EndRead),
  obj);
  }

  private void EndRead(IAsyncResult result)
  {
  int length = _filestream.EndRead(result);
  ReadFileObject state = (ReadFileObject)result.AsyncState;
  int index = state.Index;
  byte[] buffer = state.Buffer;
  //...其它操作
  }

  #region IDisposable 成员

  public void Dispose()
  {
  if (_filestream != null)
  {
  _filestream.Flush();
  _filestream.Close();
  _filestream.Dispose();
  _filestream = null;
  }
  }

  #endregion

外部使用Read(int index)开始异步读取,可是文件还没有读完,而要取消读取时调用Dispose();
但是有时候取消后EndRead(IAsyncResult result)还会被调用。。因此就出错。
现在是怎么样在开始异步读取后,能取消。如果加个变量来判断是否被取消的话,就要维护这个变量。
有没有其它的方法呢?

[解决办法]
up
[解决办法]
我的tcl好像也有这问题,帮你顶
但是endread等都是阻塞 提前释放不知道什么状态
[解决办法]

1.不能在AsyncCallback委托中调用EndRead方法了,因为调用了EndRead方法就会阻塞主线程直到异步方法完成
2.有条件的调用EndRead方法,并将异步方法涉及到的资源释放有返回值则另赋返回值

C# code
// AsynCall3.cs// 异步调用示例: 轮询异步调用是否完成using System;using System.Threading;// 定义异步调用方法的委托// 它的签名必须与要异步调用的方法一致public delegate int AsynComputeCaller(ulong l, out ulong factorial);public class Factorial{    // 计算阶乘    public ulong Compute(ulong l)    {        Thread.Sleep(80);        if (l == 1)        {            return 1;        }        else        {            return l * Compute(l - 1);        }    }    // 要异步调用的方法    // 1. 调用Factorial方法来计算阶乘,并用out参数返回    // 2. 统计计算阶乘所用的时间,并返回该值    public int AsynCompute(ulong l, out ulong factorial)    {        Console.WriteLine("开始异步方法");        DateTime startTime = DateTime.Now;        factorial = Compute(l);        TimeSpan usedTime = new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);        Console.WriteLine("\n结束异步方法");        return usedTime.Milliseconds;    }}public class Test{    public static void Main()    {        // 创建包含异步方法的类的实例        Factorial fact = new Factorial();        // 创建异步委托        AsynComputeCaller caller = new AsynComputeCaller(fact.AsynCompute);        // 启动异步调用        Console.WriteLine("启动异步调用");        ulong l = 30;        ulong lf;        IAsyncResult result = caller.BeginInvoke(l, out lf, null, null);        // 轮询异步方法是否结束        Console.WriteLine("主线程进行一些操作");        while (result.IsCompleted == false)        {            // 主线程进行一些操作            Thread.Sleep(33);            Console.Write(".");        }        // 主线程进行一些操作        Thread.Sleep(0);              int returnValue;        //按A取消异步操作        if (Console.ReadKey().Key == ConsoleKey.A)        {            returnValue = 0;            Console.WriteLine("异步方法已经结束,主线程进行另外一些操作");        }        else        {   // 调用EndInvoke来获得结果            returnValue = caller.EndInvoke(out lf, result);        }        // 异步调用的方法已经结束,显示结果        Console.WriteLine("已经得到结果:{0}的阶乘为{1},计算时间为{2}毫秒", l, lf, returnValue);        Console.Read();    }} 


[解决办法]
执行过程中取消可以用BackgroundWorker,它支持动态取消异步操作
调用CancelAsync()方法即可
[解决办法]

我也是遇到异步的问题,
不过我的是UdpClient。client.BeginReceive(new AsyncCallback(ReceiveCallback),null);
如果需要关闭调用client.Close()的话,在ReceiveCallback里面调用client.EndReceive就会报“无法访问已释放的对象”

不知道你的解决了没有,怎么解决的?
[解决办法]
且我的是只要调用client.Close()。client就会调用BeginReceive指定的那个回调方法。
我的那个回调方法里面调用client.EndReceive方法

热点排行