大量数据转录的多线程和同步处理实现

项目中需要对两个不同格式的存储设备进行数据转录,因为数据量非常大,所以时间非常缓慢;解决方案是使用ReaderWriterSlim类建立一个共享的同步数据,可以支持一个线程读取外部设备,向同步数据写入;多个线程从同步数据中读取,转换格式,然后写入到本地设备。

本例中采用Queue<T>作为存放数据的集合,写入线程向它的尾部写入对象,读取线程从它的头部获取对象。

需要注意的是,由于Queue会抛弃已处理的对象,所以在同步数据队列中无法验证数据对象的唯一性,被写入的数据库需要去掉唯一约束,或在写入时向数据库请求验证。

首先定义一个读写接口: 

 

namespace  Common
{
    
public   interface  IReaderWriter < T >
    {
        T Read(
int  argument);
        
void  Write( int  arugment, T instance);
        
void  Delete( int  argument);
        
void  Clear();
    }
}

 

然后实现一个队列的读写器:

 

namespace  Common
{
    
public   class  QueueReaderWriter < T >  : IReaderWriter < T >
    {
        
private  Queue < T >  queues;

        
public  QueueReaderWriter()
        {
            queues 
=   new  Queue < T > ();
        }

        
public  QueueReaderWriter( int  capacity)
        {
            queues 
=   new  Queue < T > (capacity);
        }

        
#region  IReadWrite<T> 成员

        
public  T Read( int  argument)
        {
            
return  queues.FirstOrDefault();
        }

        
public   void  Write( int  arugment, T instance)
        {
            queues.Enqueue(instance);
        }

        
public   void  Delete( int  argument)
        {
            queues.Dequeue();
        }

        
public   void  Clear()
        {
            queues.Clear();
            queues.TrimExcess();
        }

        
#endregion
    }
}

 

使用ReaderWriterLockSlim实现同步数据类:

namespace  Common
{
    
public   class  SynchronizedWriteData < T >  : IDisposable
    {
        
private  ReaderWriterLockSlim _dataLock  =   new  ReaderWriterLockSlim();
        
private  IReaderWriter < T >  _innerData;

        
private  SynchronizedWriteData()
        { }

        
public  SynchronizedWriteData(IReaderWriter < T >  innerData)
        {
            _innerData 
=  innerData;
        }

        
public  T Read()
        {
            _dataLock.EnterReadLock();
            
try
            {
                
return  _innerData.Read( 0 );
            }
            
finally
            {
                _dataLock.ExitReadLock();
            }
        }

        
public  T Read( int  argument)
        {
            _dataLock.EnterReadLock();
            
try
            {
                
return  _innerData.Read(argument);
            }
            
finally
            {
                _dataLock.ExitReadLock();
            }
        }

        
public   void  Add(T instance)
        {
            _dataLock.EnterWriteLock();
            
try
            {
                _innerData.Write(
0 , instance);
            }
            
finally
            {
                _dataLock.ExitWriteLock();
            }
        }

        
public   void  Add( int  argument, T instance)
        {
            _dataLock.EnterWriteLock();
            
try
            {
                _innerData.Write(argument, instance);
            }
            
finally
            {
                _dataLock.ExitWriteLock();
            }
        }

        
public   bool  AddWithTimeout(T instance,  int  timeout)
        {
            
if  (_dataLock.TryEnterWriteLock(timeout))
            {
                
try
                {
                    _innerData.Write(
0 , instance);
                }
                
finally
                {
                    _dataLock.ExitWriteLock();
                }
                
return   true ;
            }
            
else
            {
                
return   false ;
            }
        }

        
public   bool  AddWithTimeout( int  argument, T instance,  int  timeout)
        {
            
if  (_dataLock.TryEnterWriteLock(timeout))
            {
                
try
                {
                    _innerData.Write(argument, instance);
                }
                
finally
                {
                    _dataLock.ExitWriteLock();
                }
                
return   true ;
            }
            
else
            {
                
return   false ;
            }
        }

        
public   void  Delete()
        {
            _dataLock.EnterWriteLock();
            
try
            {
                _innerData.Delete(
0 );
            }
            
finally
            {
                _dataLock.ExitWriteLock();
            }
        }

        
public   void  Delete( int  argument)
        {
            _dataLock.EnterWriteLock();
            
try
            {
                _innerData.Delete(argument);
            }
            
finally
            {
                _dataLock.ExitWriteLock();
            }
        }

        
#region  IDisposable 成员

        
public   void  Dispose()
        {
            
try
            {
                _dataLock.EnterWriteLock();
                {
                    
try
                    {
                        _innerData.Clear();
                    }
                    
finally
                    {
                        _dataLock.ExitWriteLock();
                    }
                }
            }
            
finally
            {
                _dataLock.Dispose();
            }
        }

        
#endregion
    }
}

 

namespace  ExternalDataHandle
{
    
///   <summary>
    
///  从外部数据源获取到内部数据源的适配器抽象类
    
///   </summary>
    
///   <typeparam name="T"> T 数据对象类型 </typeparam>
     public   abstract   class  ExternalDataAdapter < T >  : IDisposable
    {
        
///   <summary>
        
///  外部数据源连接字符串
        
///   </summary>
         protected   abstract   string  ConnectString {  get ; }

        
///   <summary>
        
///  提供初始化数据适配器的方法
        
///   </summary>
         protected   abstract   void  Initialize();

        
///   <summary>
        
///  提供数据传递的方法
        
///   </summary>
         public   abstract   void  Transmit();

        
///   <summary>
        
///  提供从外部数据设备读取数据的方法
        
///   </summary>
         protected   abstract   void  ReadFromExternalDevice();

        
///   <summary>
        
///  提供保存数据到内部设备的方法
        
///   </summary>
         protected   abstract   void  SaveToInternalDevice();

        
#region  IDisposable 成员

        
public   abstract   void  Dispose();

        
#endregion
    }
}

 

多线程数据转录类,本例只使用了一个读取线程:

namespace  ExternalDataHandle
{
    
///   <summary>
    
///  提供多线程方式从外部数据源获取到内部数据源的适配器类
    
///   </summary>
    
///   <typeparam name="T"></typeparam>
     public   abstract   class  MultiThreadAdapter < T >  : ExternalDataAdapter < T >
    {
        
protected  SynchronizedWriteData < T >  _data;
        
protected  Thread _readThread;

        
protected   abstract   override   string  ConnectString {  get ; }

        
protected   abstract   override   void  Initialize();

        
public   sealed   override   void  Transmit()
        {
            _readThread 
=   new  Thread( new  ThreadStart(ReadFromExternalDevice));
            _readThread.Start();
            Thread.Sleep(
10000 );
            
while  (_readThread.IsAlive)
            {
                SaveToInternalDevice();
            }
            _readThread.Join();
        }

        
protected   abstract   override   void  ReadFromExternalDevice();

        
protected   abstract   override   void  SaveToInternalDevice();

        
public   override   void  Dispose()
        {
            
if  (_data  !=   null )
            {
                _data.Dispose();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值