提前中止异步线程

原帖:http://search.csdn.net/Expert/topic/1145/1145048.xml?temp=.9395105
问题:
当启动一个异步调用时,由于这个调用很废时,有时需要提前终止,请问如果在异步调用 Completed 之前,结束此调用。

一个比较好的回答:(来自CSDN dy_2000_abc(芝麻开门) ( 三星(高级)) )
这个问题不太容易说明白,主要的思路是把整个异步操作过程分为若干段,每一段完成后判断条件,如果条件成立又调用自己,否则终止操作。
下面是我以前写的代码,这个类的功能是下载文件,每下载1k它就会引发OnProgress事件,你可以在事件中设置事件参数DownLoadEventArgs的IsCancel属性来决定是否终止下载。
代码:

using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;

namespace DownLoadControl
{
    
public class DownLoadEventArgs : EventArgs
    
{
private bool isCancel;//设置是否终止的标志
    private long bytesRecieved;
        
public long BytesRecieved     //接收字节数
        {
            
set {bytesRecieved=value;}
            
get {return bytesRecieved;}
        }


        
private long totalBytes;
        
public long TotalBytes  //总字节数
        {
            
set {totalBytes=value;}
            
get {return totalBytes;}
        }

public bool IsCancel
{
set {isCancel=value;}
get {return isCancel;}
}


    }

    
class DownLoadInfo
    
{
        
private long bytesRead=0;
        
public long BytesRead  
        
{
            
set {bytesRead=value;}
            
get {return bytesRead;}
        }

        
private long bytesTotal=-1;
        
public long BytesTotal
        
{
            
set {bytesTotal=value;}
            
get {return bytesTotal;}
        }

        
public byte[] bytesBuffer=new byte[1024];
        
private WebRequest request=null;
        
public WebRequest Request
        
{
            
set {request=value;}
            
get {return request;}
        }

        
private Stream responseStream=null;
        
public Stream ResponseStream
        
{
            
set {responseStream=value;}
            
get {return responseStream;}
        }


    }

    
    
public class DownLoadControl:Component
    
{
        
public delegate void Complete(object sender,DownLoadEventArgs e);
        
public delegate void Progress(object sender,DownLoadEventArgs e);

        
public event Complete OnComplete;   //下载完成事件
        public event Progress OnProgress;    //下载进度事件

        
private DownLoadInfo downLoadInfo=null;
        
private FileStream downLoadStream=null;
        
private ManualResetEvent allDone=new ManualResetEvent(false);
        
        
public DownLoadControl()
        
{
            downLoadInfo
=new DownLoadInfo();
        }

        
protected void CompleteDownLoad(IAsyncResult ar)
        
{            
       
        WebResponse response
=downLoadInfo.Request.EndGetResponse(ar);
            downLoadInfo.ResponseStream
=response.GetResponseStream();
            downLoadInfo.BytesTotal
=Convert.ToInt64(response.Headers["Content-Length"]);//获取需要下载的总字节数
        
        downLoadInfo.ResponseStream.BeginRead(downLoadInfo.bytesBuffer,
0,1024,new AsyncCallback(DownLoadProgress),downLoadInfo);
        }

        
protected void DownLoadProgress(IAsyncResult ar)
        
{
        
        
int dataRead=downLoadInfo.ResponseStream.EndRead(ar);
            
if (dataRead>0)
            
{
                downLoadStream.Write(downLoadInfo.bytesBuffer,
0,downLoadInfo.bytesBuffer.Length);
                downLoadInfo.BytesRead
+=dataRead;
                
if (this.OnProgress!=null)
                
{
                DownLoadEventArgs args
=new DownLoadEventArgs();
                    args.TotalBytes
=downLoadInfo.BytesTotal;
                    args.BytesRecieved
=downLoadInfo.BytesRead;
                    
this.OnProgress(this,args);
                                                                                
if (args.IsCancel)//如果被终止,退出
                                                                               {
                                                                                downLoadInfo.ResponseStream.Close();
                                             downLoadStream.Close();
                                       allDone.Set();
                                                                                
return;
                                                                                }

                }

                downLoadInfo.ResponseStream.BeginRead(downLoadInfo.bytesBuffer,
0,1024,new AsyncCallback(DownLoadProgress),downLoadInfo);
            }

            
else
            
{
            downLoadInfo.ResponseStream.Close();
            downLoadStream.Close();
                allDone.Set();
            }

                
        }

        
protected void DownLoad()
        
{
            
try
            
{
                downLoadInfo.Request
=WebRequest.Create(new Uri(this.URL)); //建立连接
            }

            
catch (Exception E)
            
{
                MessageBox.Show(E.Message);
                
return;                
            }

            
catch 
            
{
            MessageBox.Show(
"无法建立连接");
                
return;            
            }

            
if (File.Exists(this.Distination))
            
{
            
if (MessageBox.Show("","文件"+this.Distination+"已经存在,是否代替原文件?",MessageBoxButtons.YesNo)==DialogResult.No)
                
return;
            }

            
try
            
{
            downLoadStream
=File.Create(this.Distination);
            }

            
catch (Exception E)
            
{
                MessageBox.Show(E.Message);
                
return;
            }

            
catch 
            
{
                MessageBox.Show(
"无法建立指定的文件");
                
return;
            }

            allDone.Reset();
            
            downLoadInfo.Request.BeginGetResponse(
new AsyncCallback(CompleteDownLoad),downLoadInfo); //开始接收数据
            allDone.WaitOne();
            
if (this.OnComplete!=null)
            
{
                DownLoadEventArgs args
=new DownLoadEventArgs();
                args.TotalBytes
=downLoadInfo.BytesTotal;
                args.BytesRecieved
=downLoadInfo.BytesRead;
                
this.OnProgress(this,args);
            }


        }


        
public void Start()
        
{
        System.Threading.Thread a
=new System.Threading.Thread(new System.Threading.ThreadStart(this.DownLoad));  //新建一个线程
        a.Start();    //开始下载
        }



        
属性
    }

}


posted on 2004-11-03 17:25  团团ta爸  阅读(858)  评论(0编辑  收藏  举报

导航