1

I have a c# 4.0 library that is instantiated by a C++ MFC client and I am trying to use a the TPL to provide an asynchronous task facility that releases the client's thread and ultimately raises a completed event on the clients 'Main Thread'.

Because I have no UI there is no Synch Context so the old FromCurrentSynchronisationConext problem arises. I figured I could install a context if I can be sure the client is a COM STA client so I have read many posts about how to tell if you are on the 'Main Thread' but the suggested tests (i.e. How to tell if a thread is the main thread in C#) fails because surprisingly we appear to be on a background thread. The Thread ID is 1, it is STA, it is not a ThreadPool thread and it is alive but why is it thinking it is a background thread??

Assuming I ignore that part of the test and continue to install a new WindowsFormsSynchronizationContext, is this safe? Essentially I'm saying 'OK this is our C++ app's thread so if I stick this context in I can pretend it's a .Net UI thread and marshal calls back to it'

Is there a safe way of doing this?

One last thing...why does the C++ app appear to receive my background thread raised events on the main thread anyway!! Is it even worth the effort of trying to marshal or just let it 'magically' happen?

Losing my mind so any help would be appreciated!!

Community
  • 1
  • 1
Akuma
  • 551
  • 1
  • 5
  • 21
  • As far as i am aware, background threads are different to worker threads. http://msdn.microsoft.com/en-us/library/h339syd0%28v=vs.110%29.aspx I would ignore that part of the test although it will be legal for the thread to be killed without warning. – Gusdor Aug 05 '14 at 15:03
  • So would you say in my scenario it is sufficient to do this (sorry I can't seem to format this as code): if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA && !Thread.CurrentThread.IsThreadPoolThread && Thread.CurrentThread.IsAlive) { SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext()); } – Akuma Aug 05 '14 at 15:12
  • `Thread.CurrentThread.IsAlive` will always be `true`! Is a threadpool thread a requirement? You can probably omit it. – Gusdor Aug 05 '14 at 15:20
  • My requirement is to decide if the caller of my library is a COM client such as C++ MFC or VB6 and if so then (and only if it's safe) install a context for callback purposes. I could well be called from a .Net process in which case I will use the current scheduler if one exists and leave it up to the calling process to install one if it needs. – Akuma Aug 05 '14 at 15:23
  • you really only need to check the apartment state. – Gusdor Aug 05 '14 at 15:29
  • If you have no UI then the odds that the C++ code is pumping a message loop are rather low as well. Rock-hard requirement for an STA thread, you can't get a SynchronizationContext going if that isn't done. You'd better take care of it yourself. Perhaps [with this](http://stackoverflow.com/a/21684059/17034). – Hans Passant Aug 05 '14 at 15:33
  • Related: http://stackoverflow.com/q/21211998/1768303 – noseratio Aug 05 '14 at 20:20
  • Well the MFC application currently utilizing my library does have a UI but you are right that I can't guarantee who will consume my library in the future. I have decided rather than to figure out if there is a message loop on the main application (something I'm not sure is possible in my case) then I will simply see if there is a non default task scheduler installed and use it (or default otherwise) – Akuma Aug 12 '14 at 09:24

0 Answers0