Results 1 to 11 of 11

Thread: [2008] Using .NET async methods

  1. #1

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Exclamation [2008] Using .NET async methods

    I have noticed that the .NET framework contains extensive amounts of asynchronous methods (identified by the Begin and End keywords). They usually take an AsyncCallback (or other callbacks) and an Object as parameters. Unfortunately, given my limited experience with multithreading, I was unable to understand the MSDN documentation on the proper use of callbacks and am now left dead in the water with my current project. How do I use the callback objects?

    Can anyone please show me a proper way to fill an array of bytes by using multiple threads (or the ThreadPool) for a sub which takes two Integers as parameters? When I try to add arguments to a method after the AddressOf keyword, it tries to treat the method as an array, resulting in an error.

    The scenario is as follows:
    A byte array needs to be filled with data. The data is received from a server via the WebResponse stream. Since the server must be contacted several times, possibly with different URIs every time, the interaction must be concurrent. Then each response must be written at the appropriate position in the byte array. In the end, the byte array must be returned to the calling thread.

    I know that it is unusual to write to an array concurrently, but it's an application requirement. Unless someone proposes a better method to get the data concurrently and then write it in an array with the same effect, of course.
    Last edited by obi1kenobi; Dec 30th, 2008 at 02:53 PM.
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

  2. #2
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: [2008] Using .NET async methods

    You're basically talking about something like a torrent download? Where different parts of the file are downloaded from different users? You wouldn't write to the byte array at the same time from different threads. You would create as many arrays as you have URI's, and fill each array at appropriate positions with the appropriate info. Then when all are finished you add them together.

  3. #3

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Re: [2008] Using .NET async methods

    Well the file itself doesn't exist "as is" anywhere, instead it is created from multiple parts from multiple users, so I guess you could say it's similar to a torrent.

    I considered the option you are proposing, however I abandoned it because I could not track the progress of each array. How would I know when a certain array is filled and ready to be transferred to the master array? AFAIK it should be related to my callback question in my previous post...
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

  4. #4
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: [2008] Using .NET async methods

    Could you post some of the code you are using in the WebResponse? And how is this data retrieved? Is each part a consecutive group of bytes? With a bit more data, I think I can help you out.

  5. #5

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Re: [2008] Using .NET async methods

    ATM I do not have access to my code since it is on a different pc from the one I'm using. However, I will try to provide as much info as possible and if you still need the code then I will post it as soon as I can.

    The WebResponse contains a stream object in one of its properties, which in turn is populated by plain binary data. I use a BinaryReader to retrieve the bytes of data from the stream and place them in an array. It would be nice if the order of the bytes could be kept between WebResponses (e.g. the first response would return the first series of bytes etc.), however it is not necessary and may be avoided if it complicates matters.
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [2008] Using .NET async methods

    Have you read this?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: [2008] Using .NET async methods

    Having read your first post more carefully it seems to me that you should build this solution up in two parts. First, use the ThreadPool to write to your array, e.g.
    vb.net Code:
    1. Module Module1
    2.  
    3.     Sub Main()
    4.         Dim stream As IO.Stream
    5.         Dim array As Byte()
    6.  
    7.         Threading.ThreadPool.QueueUserWorkItem(AddressOf WriteToArray, _
    8.                                                New ArrayWriteData With {.Array = array, _
    9.                                                                         .Offset = 0, _
    10.                                                                         .Count = 0, _
    11.                                                                         .Stream = stream})
    12.         Threading.ThreadPool.QueueUserWorkItem(AddressOf WriteToArray, _
    13.                                                New ArrayWriteData With {.Array = array, _
    14.                                                                         .Offset = 0, _
    15.                                                                         .Count = 0, _
    16.                                                                         .Stream = stream})
    17.         Threading.ThreadPool.QueueUserWorkItem(AddressOf WriteToArray, _
    18.                                                New ArrayWriteData With {.Array = array, _
    19.                                                                         .Offset = 0, _
    20.                                                                         .Count = 0, _
    21.                                                                         .Stream = stream})
    22.     End Sub
    23.  
    24.     Private Sub WriteToArray(ByVal state As Object)
    25.         Dim awd As ArrayWriteData = DirectCast(state, ArrayWriteData)
    26.  
    27.         awd.Stream.Read(awd.Array, awd.Offset, awd.Count)
    28.     End Sub
    29.  
    30. End Module
    31.  
    32.  
    33. Friend Structure ArrayWriteData
    34.     Public Array As Byte()
    35.     Public Offset As Integer
    36.     Public Count As Integer
    37.     Public Stream As IO.Stream
    38. End Structure
    Obviously that code won't work as is. You'd have to actually create an array for a start, plus use proper values for the offset and count each time. Also, your streams will come from your WebResponses.

    Once you've got that part working properly, then you can look at using BeginGetResponse to get your responses asynchronously instead of using GetResponse to get them synchronously.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: [2008] Using .NET async methods

    Your webresponses contain streams of bytes.

    Lets say that you have a empty 200 byte array. And you are retrieving streams from 4 locations. One stream has bytes 0-49, one has 50-99, one has 100-149 and one has 150-199. How does the program know which stream contains the bytes for which location?

  9. #9

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Re: [2008] Using .NET async methods

    @jmcilhinney:
    Thanks for the great link, I'll try to make the most of it.

    The code you provided enabled me to understand the use of the ThreadPool much better. I'll try it in my project as soon as possible. Just one thing - how about using GetResponse in the sub executed by the ThreadPool? Wouldn't it be a cleaner solution than using BeginGetResponse before starting the ThreadPool WorkItems? I am unexperienced, so I'm asking for your opinion before I do anything I might regret later

    @MaximilianMayrhofer:
    Well when a WorkItem is enqueued in the ThreadPool, the appropriate arguments will be passed, ensuring that the bytes read from its Stream will be placed at their appropriate positions. The point is that the WorkItem will query the server, get the info and write it to the predetermined location.
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

  10. #10

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Re: [2008] Using .NET async methods

    Just one thing left to solve now I think. How do I detect when all the tasks in the ThreadPool have finished executing? Since I need to pass the finished byte array along...

    Is WaitHandle the way to go or do you have another suggestion?

    EDIT:
    Ok I made some changes to the code, so now it uses WaitHandles and AutoResetEvents. The problem is that I'm getting a NotSupportedException on the WaitHandle.WaitAll(waitHandles) line, saying the following: "WaitAll for multiple handles on a STA thread is not supported.". I've added the <MTAThreadAttribute()> attribute before the method using WaitHandles, however this has no effect. Any ideas?
    Last edited by obi1kenobi; Dec 31st, 2008 at 12:08 PM.
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

  11. #11

    Thread Starter
    Frenzied Member obi1kenobi's Avatar
    Join Date
    Aug 2007
    Posts
    1,091

    Re: [2008] Using .NET async methods

    Bump. This issue is a serious one and I cannot solve it by myself. I need your help!
    Please rate helpful ppl's posts. It's the best 'thank you' you can give

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