日期:2014-05-18  浏览次数:21362 次

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)