Answered by:
Asynchronous BeginInvoke problem - threadid remains same?

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:
- 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!
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:
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, December 22, 2009 5:19 PM