杀死异步线程

时间:2013-03-18 03:59:15

标签: c# multithreading asynchronous threadpool

我正在尝试异步读取HttpResponse.GetResponseStream()

 Stream source=myHttpResponse.GetResponseStream();
 IAsyncResult asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);

但由于某种原因,我的应用程序挂起在source.Endread()

int bytesRead = source.EndRead(innerAsyncResult);

我知道所有的异步调用都依赖于Threadpool,但有什么方法可以杀死线程,

我确实放了几个控件来杀死异步操作

  1. 我已经放置了一个外部计时器,On Trigger我关闭了流

    System.Threading.Timer timer = new System.Threading.Timer(OnTimerCallback, source, Convert.ToInt32(new TimeSpan(0, 10, 0).TotalMilliseconds), 1); 
    
    private static void OnTimerCallback(Object state)
    {
        Stream stream = state as Stream;
    
        if (stream == null)
            return;
    
        try
        {
            stream.Close();
            stream.Dispose();
    
        }
        catch (Exception ex)
        {
            //Log Error
        }
    
        throw new Exception("Successfully closed the Stream and killing the Thread");
    }
    

    它正在关闭流,但由于某种原因,应用程序仍然挂起。

  2. 我已经放置了一个外部计时器,并关闭了asyncResult.AsyncWaitHandle.Close()

  3. 这两种机制似乎都是徒劳的,有什么方法可以杀死线程。

    基本上我想要实现的是从NetworkStream读取并将其保存在FileStream中,它可以正常工作一段时间,之后它挂在source.EndRead(innerAsyncResult);从Networkstream读取是异步的,其中将数据保存到文件流是同步的。

    实际代码:

    public static void CopyToStreamAsync(this Stream source, Stream destination,
        Action<Stream, Stream, Exception> completed, Action<uint> progress,
        uint bufferSize)
    {
        byte[] buffer = new byte[bufferSize];
    
        Action<Exception> done = exception =>
            { //Completed event handler
             };
    
        int maxDownloadSize = maximumDownloadSize.HasValue
            ? (int)maximumDownloadSize.Value
            : int.MaxValue;
    
        int bytesDownloaded = 0;
        IAsyncResult asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);
    
        Action<IAsyncResult, bool> endRead = null;
        endRead = (innerAsyncResult, innerIsTimedOut) =>
            {
                try
                {
                    int bytesRead = source.EndRead(innerAsyncResult);
    
                    int bytesToWrite = new[] { maxDownloadSize - bytesDownloaded, buffer.Length, bytesRead }.Min();
    
                    destination.Write(buffer, 0, bytesToWrite);
                    bytesDownloaded += bytesToWrite;
    
                    if (!progress.IsNull() && bytesToWrite > 0)
                    {
                       //Progress Handlers 
                    }
    
                    if (bytesToWrite == bytesRead && bytesToWrite > 0)
                    {
                        asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);                       
                        asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
                    }
                    else
                    {
                        done(null);
                    }
                }
                catch (Exception exc)
                {
                    done(exc);
                }
            };
    
        asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
    }
    

0 个答案:

没有答案