locked
Asynchronous BeginInvoke problem - threadid remains same? RRS feed

  • Question

  • User1269867951 posted

    Hi,

    Here is my code to execute an async operation. MY question is that the log file shows same threadid for page_load event and the method being invoked using begininvoke.



    Am I doing something wrong?


    Thanks


    Private Delegate Sub AppendAllTextDelegate(ByVal path As String, ByVal content As String)
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            IO.File.AppendAllText("d:\test\app_data\log2.txt", ControlChars.CrLf & System.DateTime.Now() & "--" & "Page_Loaded on thread: " & Threading.Thread.CurrentThread.GetHashCode().ToString())
    
            Dim myDelegateInstance As New AppendAllTextDelegate(AddressOf AppendAllTextBackground)
            Dim myCallBackInstance As New AsyncCallback(AddressOf ResultCallBack)
            myDelegateInstance.BeginInvoke("d:\test\app_data\log2.txt", ControlChars.CrLf & System.DateTime.Now & "--" & "File Operation Complete on thread: " & Threading.Thread.CurrentThread.GetHashCode().ToString(), myCallBackInstance, myDelegateInstance)
    
    
    
    
        End Sub
    
        Private Sub AppendAllTextBackground(ByVal path As String, ByVal content As String)
            System.Threading.Thread.Sleep(10000)
            IO.File.AppendAllText(path, content)
    
        End Sub
    
        Private Sub ResultCallBack(ByVal ar As IAsyncResult)
            Dim myDelegateInstance As AppendAllTextDelegate = CType(ar.AsyncState, AppendAllTextDelegate)
            myDelegateInstance.EndInvoke(ar)
    
        End Sub
    


    Monday, December 21, 2009 11:25 PM

Answers

  • User-952121411 posted

    No, it may have more to do with the way you are trying to access the thread ID via GetHashCode().  After doing a little more research, getting the actual thread ID seems to be more cumbersome than you might think.

    Take a look at the following links:

    Why is getting a Thread ID so hard?: 

    http://www.theserverside.net/news/thread.tss?thread_id=26697

    ...and a comment interesting from the link above: "The point is, that the runtime may switch the OS-Thread - .Net-Thread mapping during runtime. Thus trying to retrieve the physical ThreadID is not of much help, as it may change at any time."

    An alternative method to get a Thread ID which supersedes the obsolete AppDomain.GetCurrentThreadId Method:

    Thread.ManagedThreadId Property:

    http://msdn.microsoft.com/en-us/library/system.threading.thread.managedthreadid.aspx

    Thread and Process Identifiers vs. GetHashCode():

    http://www.dasblonde.net/PermaLink.aspx?guid=03ba66f1-ef8b-4ca3-8ada-852000b6feb9

    Thread IDs and .NET:

    http://www.interact-sw.co.uk/iangblog/2004/06/21/dotnetthreadid

    Lastly, I may ask why you are trying to get the Thread ID anyways if you are not really using it for anything important?  Are you just trying to confirm that your asynchronous delegate is working properly?  Easy, just set a timer as you have for like 1 minute to log something, and let the page finish loading.  If 1 minute later you get a log entry and all that time your page was still functional, then your code worked successfully.<!---->

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 22, 2009 12:33 PM
  • User-952121411 posted

    I figured it may not work properly, as the more complex code has difficulty in the converters.  I do not immediately know what that code does, but I recommend re-posting that code and the question about how it works in the C# forum.  You should be able get some good feedback there in regards to that specific code.

    C# ASP.NET Forum: 

    http://forums.asp.net/37.aspx

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 22, 2009 5:19 PM

All replies

  • User-952121411 posted

     Yes, I think the problem lies in the following statement you are using to ID the thread:

    Threading.Thread.CurrentThread.GetHashCode().ToString()


    The problem is that line is called before the delegate executes asynchronously, and is actually being assigned by the main UI thread, and thus gives you the same ID for both.  I believe if you moved that logging call inside the 'AppendAllTextBackground()' method, you would see the different thread ID.

    An asyncronous delegate should be called on a thread from the thread pool, so within that same method (AppendAllTextBackgroundasynchronous) you could test the following line of code as well:

    Dim IsThreadPoolThread As Boolean = Thread.CurrentThread.IsThreadPoolThread

    ...which should indicate you are running on a separate thread.  Here is a link with a high level description from the MSDN as well that may help explain things further:

    Asynchronous Programming Using Delegates:

    http://msdn.microsoft.com/en-us/library/22t547yb.aspx

    Hope this helps! Smile

    Tuesday, December 22, 2009 10:15 AM
  • User1269867951 posted

    Hi

    Thanks for your reply. I figured that out right after posting this post on the forums. However, even when I move the logging into AppendAllTextBackground method, threadid still remains same.


    Could it be because threadpool id is being used? And since page_load is already done, the same thread id (as was used for page_load) is being used for appendalltextbackground as well? Could that be it?


    Thanks


    Tuesday, December 22, 2009 12:02 PM
  • User-952121411 posted

    No, it may have more to do with the way you are trying to access the thread ID via GetHashCode().  After doing a little more research, getting the actual thread ID seems to be more cumbersome than you might think.

    Take a look at the following links:

    Why is getting a Thread ID so hard?: 

    http://www.theserverside.net/news/thread.tss?thread_id=26697

    ...and a comment interesting from the link above: "The point is, that the runtime may switch the OS-Thread - .Net-Thread mapping during runtime. Thus trying to retrieve the physical ThreadID is not of much help, as it may change at any time."

    An alternative method to get a Thread ID which supersedes the obsolete AppDomain.GetCurrentThreadId Method:

    Thread.ManagedThreadId Property:

    http://msdn.microsoft.com/en-us/library/system.threading.thread.managedthreadid.aspx

    Thread and Process Identifiers vs. GetHashCode():

    http://www.dasblonde.net/PermaLink.aspx?guid=03ba66f1-ef8b-4ca3-8ada-852000b6feb9

    Thread IDs and .NET:

    http://www.interact-sw.co.uk/iangblog/2004/06/21/dotnetthreadid

    Lastly, I may ask why you are trying to get the Thread ID anyways if you are not really using it for anything important?  Are you just trying to confirm that your asynchronous delegate is working properly?  Easy, just set a timer as you have for like 1 minute to log something, and let the page finish loading.  If 1 minute later you get a log entry and all that time your page was still functional, then your code worked successfully.<!---->

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 22, 2009 12:33 PM
  • User1269867951 posted

    Hi,

    Yes I am trying to get id to confirm that async operation is working correctly.

    Right now this is what happens in the visual studio IDE

    i) Page finishes loading and there is a message in VS that file log.txt has changed

    ii) I check the page in browser and it has rendered and is functional

    iii) Ten seconds later I get another message in IDE that log.txt has changed. This time there is entry from async operation.


    Is this what you are referring to in your last suggestion? That means my code is working as intended?

    Thanks


    Tuesday, December 22, 2009 12:58 PM
  • User1269867951 posted

    Also, while we are at it, do you think would you be able to translate this into VB.NET? I have been scratching my head since last night to figure out how to translate it but no luck.


     async.PostOperationCompleted(
    delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); },
    completedArgs);


    Thanks!
    Tuesday, December 22, 2009 1:01 PM
  • User1269867951 posted

    And BTW, thanks for taking time out to bring these resources to my attention. They would be helpful. Thanks again.


    Tuesday, December 22, 2009 1:05 PM
  • User-952121411 posted

    Is this what you are referring to in your last suggestion? That means my code is working as intended?
     

    Yes and Yes.  It appears your code is working as designed and the process is happening asyncronously.

    As far as the code, I simply put it through a translator, and this is what came out:

    async.PostOperationCompleted(Function(e As Object) Do
    	OnMyTaskCompleted(DirectCast(e, AsyncCompletedEventArgs))
    End Function, completedArgs)


    However, I also too have a stronger VB.NET background and you would need to test it to make sure that is the equivilent line of code.  If you need some links to converters for the future, check out the link below:

    Tools for Converting C# code to VB.NET (or vice versa):

    http://allen-conway-dotnet.blogspot.com/2009/11/tools-for-converting-c-code-to-vbnet-or.html

     

    Tuesday, December 22, 2009 2:11 PM
  • User1269867951 posted

    Thanks again. I will look at the link. The translated code does not work in VB.NET as is. I would probably need to read it up. Do you understand what the C# code is doing? I am unable to understand it. If you can perhaps explain what the C# statement is doing (algorithm) I can try to write it up in VB.NET.

    Other than that, thanks for all your help.

    I will leave this question open for now just in case you could explain what C# statement is doing exactly. If not, its ok I will go ahead and close this assign points.


    Thank you very much!


    Tuesday, December 22, 2009 5:00 PM
  • User-952121411 posted

    I figured it may not work properly, as the more complex code has difficulty in the converters.  I do not immediately know what that code does, but I recommend re-posting that code and the question about how it works in the C# forum.  You should be able get some good feedback there in regards to that specific code.

    C# ASP.NET Forum: 

    http://forums.asp.net/37.aspx

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 22, 2009 5:19 PM