将数据库中二进制数据以异步方式写入磁盘

方式一:一次获取,异步写入
/// <summary>
  /// 缓冲区大小
  /// </summary>
  public const int numPixels = 512 * 512;
 /// <summary>
  /// 将数据文件写入磁盘
  /// </summary>
  /// <param name="strSql"></param>
  /// <returns></returns>
  public static bool  MakeFileWithWriteListByAdapter(string strSql,out string strErr)
  {
   if(File.Exists(ConfigProxy.GetValueByKey("ListFile")))File.Delete(ConfigProxy.GetValueByKey("ListFile"));
   DataTable objTable;    
   if(!OleDataBaseProxy.ExecuteSql(strSql,out objTable,out strErr))return false;
   string outputPath = ConfigProxy.GetValueByKey("OutputPath");
   if(objTable.Rows.Count < 1) return false;  
   string strDirectory = outputPath + "//";
   if(!Directory.Exists(strDirectory)) Directory.CreateDirectory(strDirectory);
   for(int i = 0;i< objTable.Rows.Count; i ++)
   {
    
    string fileName = objTable.Rows[i]["附件名称"].ToString();
    //记录输出列表
    LogProxy.WriteList(strDirectory + fileName);
    //获取文件数据
    byte [] ImageContent = (byte[])objTable.Rows[i]["附件内容"];    
    AutoResetEvent manualEvent = new AutoResetEvent(false);   
    FileStream fStream =
     new FileStream(strDirectory + fileName,FileMode.Create,
     FileAccess.ReadWrite, FileShare.None, 4096, true);   
    IAsyncResult asyncResult = fStream.BeginWrite(
     ImageContent, 0, ImageContent.Length,
     new AsyncCallback(EndWriteCallback),
     new State(fStream, manualEvent));   
    manualEvent.WaitOne(5000, false);
    fStream.Close();
   }
   strErr = "";
   return true;
  } 
class State
  {
   public FileStream fStream;
   public AutoResetEvent autoEvent;

   public State(FileStream fStream, AutoResetEvent autoEvent)
   {
    this.fStream   = fStream;
    this.autoEvent = autoEvent;
   }
  }
  static void EndWriteCallback(IAsyncResult asyncResult)
  {

   State stateInfo = (State)asyncResult.AsyncState;
   int workerThreads;
   int portThreads;
   try
   {
    ThreadPool.GetAvailableThreads(out workerThreads,
     out portThreads);   
    stateInfo.fStream.EndWrite(asyncResult);    
    Thread.Sleep(1500);
   }
   finally
   {    
    stateInfo.autoEvent.Set();
   }
  }

方式二:联机读取,异步写入

/// <summary>
  /// 缓冲区大小
  /// </summary>
  public const int numPixels = 512 * 512;
/// <summary>
  /// 将数据文件写入磁盘
  /// </summary>
  /// <param name="strSql"></param>
  /// <returns></returns>
  public static bool  MakeFileWithWriteListByReader(string strSql,out string strErr)
  { 
   if(File.Exists(ConfigProxy.GetValueByKey("ListFile")))File.Delete(ConfigProxy.GetValueByKey("ListFile"));
   string outputPath = ConfigProxy.GetValueByKey("OutputPath");
   string strDirectory = outputPath + "//";
   if(!Directory.Exists(strDirectory)) Directory.CreateDirectory(strDirectory);
   System.Data.OleDb.OleDbCommand cmd = new OleDbCommand();
   OleDbConnection Cnn = new OleDbConnection(ConfigProxy.GetValueByKey("OleConnectionString"));
   cmd.Connection = Cnn;
   cmd.CommandText = strSql;   
   //开启连接
   try
   {
    Cnn.Open();
   }
   catch(Exception Err)
   {
    strErr = Err.Message;
    return false;
   }
   byte[] pixels = new byte[numPixels];  
   OleDbDataReader reader = cmd.ExecuteReader();
   byte[]ImageContent;
   //逐条处理
   while(reader.Read())
   {
    string fileName = reader.GetString(1);
    //记录输出列表
    LogProxy.WriteList(strDirectory + fileName);
    //获取文件数据
    ImageContent = new byte[Convert.ToInt64(reader.GetString(7))];
    reader.GetBytes(6,0,ImageContent,0,Convert.ToInt32(reader.GetString(7))); 
    AutoResetEvent manualEvent = new AutoResetEvent(false);   
    FileStream fStream =
     new FileStream(strDirectory + fileName,FileMode.Create,
     FileAccess.ReadWrite, FileShare.None, 4096, true);   
    IAsyncResult asyncResult = fStream.BeginWrite(
     ImageContent, 0, ImageContent.Length,
     new AsyncCallback(EndWriteCallback),
     new State(fStream, manualEvent));   
    manualEvent.WaitOne(5000, false);
    fStream.Close();
   }
   reader.Close();
   //关闭连接
   if(Cnn.State == System.Data.ConnectionState.Open)
   {
    Cnn.Close();
   } 
   strErr = "";
   //释放资源
   Cnn.Dispose();
   cmd.Dispose();
   GC.Collect();
   return true; 
  }
  class State
  {
   public FileStream fStream;
   public AutoResetEvent autoEvent;

   public State(FileStream fStream, AutoResetEvent autoEvent)
   {
    this.fStream   = fStream;
    this.autoEvent = autoEvent;
   }
  }
  static void EndWriteCallback(IAsyncResult asyncResult)
  {

   State stateInfo = (State)asyncResult.AsyncState;
   int workerThreads;
   int portThreads;
   try
   {
    ThreadPool.GetAvailableThreads(out workerThreads,
     out portThreads);   
    stateInfo.fStream.EndWrite(asyncResult);    
    Thread.Sleep(1500);
   }
   finally
   {    
    stateInfo.autoEvent.Set();
   }
  }

 两种方式的比较:
 
方式一:适合于数据库负载较大,二进制数据大小已知的情况;
方式二:适合于数据库负载较小,二进制数据大小未知的情况;

其中:两种方式的异步机制都是相同的,没有任何区别;异步机制的优点在于充分发挥了操作系统的优点
注意:在需要对性能进行同比测试的上下文中不能采用异步机制而必须尽量采用同步机制,以提高真实性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值