views:

100

answers:

2

I am looking for a way to determine for a thread on which other thread it was originally spawned. I do not know whether a mechanism exists to do this, similar to the "Parent" property on Tasks in the new Task Parallel Library for .NET 4

Edit: Further investigation actually seems to indicate that there is no location to store this information, so short of really ugly hacks this does not appear to be possible to implement transparently.

As such I think I will accept the sample code below as the most feasible (non-transparent) answer to solve the problem, even though I'll have to look for an alternate design myself. Thanks :)

+2  A: 

The system doesn't provide such functionality internally. You can pass the thread ID of the parent thread to the thread start function pretty easily:

static class ThreadSpawner
{
    [ThreadStatic]
    private static int parentThreadId;
    public static int ParentThreadId
    {
        get { return parentThreadId; }
    }

    private class ThreadInfo
    {
        public int ParentId;
        public Action Method;
    }

    private static void StartThread(object parameter)
    {
        var threadInfo = (ThreadInfo)parameter;
        parentThreadId = threadInfo.ParentId;
        threadInfo.Method();
    }

    public static void Spawn(Action start)
    {
        new Thread(StartThread).Start(
            new ThreadInfo { 
                 Method = start, 
                 ParentId = Thread.CurrentThread.ManagedThreadId 
            });
    }
}


// Usage:
ThreadSpawner.Spawn(MyMethod);

static void MyMethod() { 
    Console.WriteLine(ThreadSpawner.ParentThreadId);
}
Mehrdad Afshari
I understand what you are trying to do here. Unfortunately in my scenario I cannot control how the code creating the threads does so. I am looking to do this in a library, so I need to be able to figure this out regardless of how the threads came into being.
jerryjvl
+2  A: 

Worse, creating a .NET thread doesn't guarantee getting a native thread so you can't depend on being able to walk the thread parent information with P/Invoke either.

I know if you write test code you will see the native thread, but it's not required to generate it and on some conditions that are difficult to guess it won't.

EDIT: can't get thread parent via P/Invoke anyway.

Joshua
I hadn't dug that deep yet, was hoping for a .NET based solution based on managed threads... but if nothing else helps, I might be interested in which P/Invoke APIs give access to the native thread information...
jerryjvl
I think I just said it won't always work. There is not a 1-1 mapping between managed threads and native threads. Now, if you really want to P/Invoke a call to CreateThread, you might find a solution, or you might find a really bad crash (I can't guess which).
Joshua
I am fully aware you said it won't always work, but investigating all avenues to their conclusion may either give me inspiration for an alternate solution, or at least give me a 'special-case' solution that may be sufficient. As such I am trying to figure out the mechanism for the "walk the thread parent information" you are alluding to in your original answer.
jerryjvl
I went back to find it, and it appears that windows kernel doesn't track thread ancestry. You will need something fancy indeed. Your own approach looks most sane. The only other one that comes to my mind is hooking CreateThread and believe me you don't want to go there.
Joshua
I briefly considered hooking... but I think I'm going to have to rely on an alternate approach. Not ready for those headaches.
jerryjvl