Results 1 to 5 of 5

Thread: Sample code for file transfer for asynchronous file copy using VB.NET

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    May 2013
    Posts
    285

    Sample code for file transfer for asynchronous file copy using VB.NET

    I have used the following code to copy files, which gives me the error for large files saying "OutOfMemoryException".
    Code:
    Private Sub ReadFilesInC()
            ' make a reference to a directory
            Dim di As New IO.DirectoryInfo("c:\")
            Dim diar1 As IO.FileInfo() = di.GetFiles()
            Dim dra As IO.FileInfo
    
            'list the names of all files in the specified directory
            For Each dra In diar1
                ReadData(dra.FullName)
            Next
        End Sub
        
    
        Public Function ReadData(ByVal Path As String)
            '--This is the state object that will contain the file 
            '---and the return data.  This class is nescessary because
            '---we dont want the return data overwritten by each 
            '---read method (like it would if it was declared globally)
            Dim tempStateObj As New StateObj
    
            '--Open up the file we wish to read
            tempStateObj.file = New System.IO.FileStream(Path, IO.FileMode.Open)
    
            '--Redimension the return data array to the appropriate length        
            ReDim tempStateObj.retData(tempStateObj.file.Length)
    
            '--Call the Asynch read method.  Pass the byte array we wish to fill
            '---the offset, the length of the file to read, the address of the
            '---callback sub, and finally a state object for our own use.
            tempStateObj.file.BeginRead(tempStateObj.retData, 0, tempStateObj.file.Length, _
                New AsyncCallback(AddressOf OnReadDone), tempStateObj)
    
            '--Control is immediately given back to the program.  The BeginRead method
            '---Does not block program execution like the Read method, so we are free to 
            '---get back to processing.
            Debug.WriteLine("BeginRead done:  " & Path)
    
            '--To show that this is a normal thread and not threadpooled:
            Debug.WriteLine(System.Threading.Thread.CurrentThread.IsThreadPoolThread)
        End Function
    
        Public Sub OnReadDone(ByVal ar As IAsyncResult)
            '--This is the asynchronous callback delegate that is called when the BeginRead
            '---is done processing.
    
            '--The state object is passed to us in ar.  It is a generic
            '---IAsyncResult, and must be casted into something usable
            '---We know we passed a StateObj class, so we cast it as such
            Dim state As StateObj = CType(ar, StateObj)
    
            '--From our state object, we must call EndRead(ar) to get the
            '---number of bytes read.  Even if you do not wish to know the 
            '---number of bytes, you must *always* call EndRead in the callback
            Dim bytesRecieved As Int32 = state.file.EndRead(ar)
    
            '--If you don't wish to know the number of bytes read, do this:
            'state.file.EndRead(ar)
    
            state.file.Close()
    
            '--Just to prove that this thread is running in a Threadpool object that 
            '---is managed by the OS:
            Debug.WriteLine(System.Threading.Thread.CurrentThread.IsThreadPoolThread)
    
            '--Open up a new file to write to
            state.file = New System.IO.FileStream("C:\Somewhere\data.txt.FileMode.Create")
    
            '--Begin the Asynch write to the file, passing everything and the state object again
            state.file.BeginWrite(state.retData, 0, state.retData.Length, New AsyncCallback(AddressOf OnWriteDone), state)
    
    
            '--At this point, the sub will terminate and the thread will go back to the
            '---internal threadpool.  It is important not to do anything that will block or take
            '---large amounts of time in this sub.  The internal threadpool is limited to
            '---25 threads total, and it is important to return the thread as quick as possible
            '---to the pool for further use.
        End Sub
    
        Public Sub OnWriteDone(ByVal ar As IAsyncResult)
            '--This is the asynchronous callback delegate that is called when the BeginWrite
            '---is done processing.
    
            '--The state object is passed to us in ar.  It is a generic
            '---IAsyncResult, and must be casted into something usable
            '---We know we passed a StateObj class, so we cast it as such
            Dim state As StateObj = CType(ar, StateObj)
    
            '--From our state object, we must call EndWrite(ar).  You must 
            '---*always* call EndWrite in the callback
            state.file.EndWrite(ar)
    
            state.file.Close()
    
            '--At this point, the sub will terminate and the thread will go back to the
            '---internal threadpool.  It is important not to do anything that will block or take
            '---large amounts of time in this sub.  The internal threadpool is limited to
            '---25 threads total, and it is important to return the thread as quick as possible
            '---to the pool for further use.
        End Sub
    
    
    
    '----------
    '--Our StateObj Class
    '----------
    
    Public Class StateObj
        Public file As System.IO.FileStream
        Public retData() As Byte
    End Class
    I have the dot net 4 so i can't use ".ReadAsync()". Please give me the sample code so that I can achieve the asynchronous file copy....

  2. #2
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: Sample code for file transfer for asynchronous file copy using VB.NET

    the error has nothing to do with synchoneous or asynchroneous but with the fact that the code tries to read the entire file into ram. why is it doing this? if the Task is just to copy the file, and i cant see anything else the code is doing, why aren't you using things like io.file.copy?

    btw. this is an excellent example where the excessive comments do not improve readability of the code...

  3. #3
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Sample code for file transfer for asynchronous file copy using VB.NET

    I agree on all cases. You run out of memory because you try to copy all bytes at the same time. A copy process should ask for a small chunk, write that chunk, then repeat until all bytes have been copied. That's why you have a length parameter. But it is a great mystery why you wouldn't just use File.Copy().

    I also agree on that commenting, most of them are completely redundant. I can't find the lines of code in the sea of comments, and you aren't really doing anything novel that warrants so many comments. You don't need to write everything twice.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    May 2013
    Posts
    285

    Re: Sample code for file transfer for asynchronous file copy using VB.NET

    Thank you for the reply...
    while surfing internet I got the details saying that asynchronous is faster than the File.Copy(). If this is wrong please explain me why?

  5. #5
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Sample code for file transfer for asynchronous file copy using VB.NET

    Like many things, it depends on how you define "faster". It's very dangerous to read an article and follow advice you don't understand, especially when it involves writing complex code that's addressed by common utility methods.

    The drive where you are storing data has a write speed, and you won't ever be faster than that. From that perspective, File.Copy() and asynchronous file I/O operate at the same speed.

    But when you make a synchronous File.Copy() call, the thread you are on will do "nothing" while that copy is happening. So if you put File.Copy() in a button's Click event handler, you might notice that your UI seems to freeze during a long file copy. That's because the thread responsible for drawing the UI and handling mouse/keyboard input is busy copying a file.

    When you make an asynchronous copy, the only difference is you are doing the copy on a worker thread. That thread is still doing "nothing" while it waits for the copy operation to finish, but since it isn't the thread where your Form is drawn or input is handled, the application doesn't look like it froze.

    From that perspective, your application remains responsive and looks faster if you do File.Copy() on a worker thread or write your own asynchronous file copy code. It's not really being faster, it is just more effeciently using the multitasking capabilities of your machine.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width