Issues with System.Threading.Timer ManagedThreadId #197
Comments
So there is a bug here. There's a separate native instance for each thread that is always kept around. You can observe this with a similar test: static void Main() {
var j = 0;
while (true) {
for (var i = 0; i < 5; i++) {
var ii = i;
var jj = j;
new Thread(() => {
while (true) {
Debug.WriteLine($"{jj} {ii} {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(500);
}
}).Start();
}
j++;
Thread.Sleep(2000);
}
} After a while the existing managed instance of the thread gets collected so the IDs begin to return 0. If we modify the test to add them to a list, the IDs stick around: static void Main() {
var j = 0;
var lst = new ArrayList();
while (true) {
for (var i = 0; i < 5; i++) {
var ii = i;
var jj = j;
var th = new Thread(() => {
while (true) {
Debug.WriteLine($"{jj} {ii} {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(500);
}
});
th.Start();
lst.Add(th);
}
j++;
Thread.Sleep(2000);
}
}
So the fixes here are to correctly copy over |
Thanks for the insight. Can you guys add the Name property for thread objects while your at it? Or would I need to open a new issue to request it? Really appreciate your help. |
A new thread would be best for that. We've split this issue up into two internal issues so will be tracking this there, closing this one. |
In the next release |
Thanks for the heads up and appreciate all your very quick responses to issues/questions. |
@Arke64 I've upgraded to v0.10.0 and still think there's an issue here. I'm getting the same ManagedThreadId of zero for both the parent thread and timer thread. Since the parent thread is still alive when the timer runs, I expected a different ManagedThreadId than the Parent. Here's the output I get:
|
Looks like there was a second part to this bug that we missed. It's been fixed for the next release. For managed thread wrappers that got GC'd, we correctly restored the ID on subsequent creation. However, the initial managed wrappers for the system threads (timer, static constructors, and the main thread) were never actually initialized with the correct ID so they're wrong from the beginning (and only until recreation after GC in 0.10.0). We've fixed that now. |
TinyCLR 0.8.0
VS2017
FEZ Spider (EMX)
I've got a couple issues with the System.Threading.Timer stemming from whether or not the callback function runs on a new thread or the same thread as it's parent (the thread that created the timer).
This code shows issue 1.
The output is:
Notice that the ManagedThreadId for the timer callback is the same value (zero) as the parent thread. However, the hash code for the timer callback is different, which tells me that it is running on a different thread. If it's running on a different thread then the ManagedThreadId should also differ from the parent thread.
Now, commenting out the while-loop
//while (!done) Thread.Sleep(50);
shows issue 2. And, that output is:This time the hash code in the timer callback is the same which tells me the timer is running on the parent thread. I'm assuming the timer is running on the parent thread because the main thread is on
Thread.Sleep(200);
. I'm not sure, if the timer callback running on the parent thread is deliberate or a bug.I ran the same exact code in a console app and no matter whether the while-loop was commented out or not, the timer callback always ran on a new thread with a different ManagedThreadId and Hash Code than the parent thread.
For issue 1, I do believe that for the same ManagedThreadId in the same application domain, we should always get the same hash code. So this appears to be a bug to me, please confirm.
For issue 2, please confirm if a timer callback should always run on a new thread or not. If not, what circumstances should it use the parent thread?
Thanks,
Rick
The text was updated successfully, but these errors were encountered: