3

I'm using thread to download something from internet. I don't have any loop inside my thread method. I'm using StreamReader.ReadToEnd() method, so when my thread is downloading something large I want to stop this thread. Preferably without Thread.Abort() method. Is it possible to give to GC thread to clean, or to finish this?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
RustamIS
  • 697
  • 8
  • 24

3 Answers3

12

Don't do a ReadToEnd, instead create a loop and read X chars at a time (or read a line at a time with ReadLine). Within the loop check whether an AutoResetEvent is set (using .WaitOne(0)), if it is then exit the loop.

Set the reset event (using Set) in your other thread when you want to stop the download.

George Duckett
  • 31,770
  • 9
  • 95
  • 162
  • +1. Read to end is really bad - forge the no abort, you possibly also use a lot of memory which yo otherwise can just not allocate to start (64 or 128k buffers may be enough). – TomTom Mar 18 '12 at 11:55
  • 1
    With a StreamReader you don't read X bytes. Replace that thought with ReadLine() – H H Mar 18 '12 at 14:07
2

You could use the BaseStream BeginRead() async method. You're better off using this rather than spawning your own dedicated thread (which consumes 1MB of committed memory). The async methods are more efficient as they use I/O completion ports.

new StreamReader(aStream).BaseStream.BeginRead()

Here's some more info http://msdn.microsoft.com/en-us/library/system.io.stream.beginread.aspx

A related thread on stopping an async read.

Stop Stream.BeginRead()

Community
  • 1
  • 1
Razor
  • 17,271
  • 25
  • 91
  • 138
0

What George Duckett says but you could use .Net 4 Task class to start the thread/asynchronous task and pass in a CancellationToken and in the loop check if IsCancellationRequested = true

Jon
  • 38,814
  • 81
  • 233
  • 382