ServerLogger - Multi-threading

1187
10
03-04-2013 04:53 AM
RichardWatson
Frequent Contributor
I have a Server Object Extension which uses threads from the thread pool.  Threads from the thread pool are, by definition, COM MTA.  When I try to log messages from an MTA thread then I find that I get various exceptions related to the RCW.  I know that ArcObjects are COM STA and that they do not deal well with MTA threads.

Just wondering if anyone has an suggestions, other than not using the thread pool, here?  What I've done is to wrap the ServerLogger in a class which simply does not log messages unless the request comes from thread that created the class, i.e. the main thread.  This stop the crashes but also causes me to lose valuable messages.

What I really wish is that the ServerLogger was able to support MTA threads.  I am not asking for all ArcObjects (that is not going to happen) but rather just the logging system.
Tags (2)
0 Kudos
10 Replies
nicogis
MVP Frequent Contributor
can be help you (Using managed ThreadPool and BackGroundWorker threads ) : http://resources.esri.com/help/9.3/arcgisengine/dotnet/2c2d2655-a208-4902-bf4d-b37a1de120de.htm ?
0 Kudos
RichardWatson
Frequent Contributor
I have seen that article.  Essentially, what ESRI advises is to not use thread pool threads.  The problem with that is that there are many nice classes from Microsoft which use it, e.g. the Task framework.
0 Kudos
nicogis
MVP Frequent Contributor
have you seen http://blogs.msdn.com/b/pfxteam/archive/2010/04/07/9990421.aspx ( ParallelExtensionsExtras ) ?
0 Kudos
RichardWatson
Frequent Contributor
Thanks for the post.  I had seen this before but it is adding yet another unsupported library to my project:(

I think that I am going to restructure my code so that I don't touch any ArcObjects in my thread pool thread.  I'll wait to do that when the thread completes.

What I really want is for ESRI to address this because their current approach makes it difficult to leverage the goodness of .NET.
0 Kudos
nicogis
MVP Frequent Contributor
For now I'm using framework 4.5 only arcgis runtime wpf ... ( in my blog I have posted a sample call soe using arcgis runtime wpf: http://nicogis.blogspot.it/2013/02/alziamo-il-livello-3d-surface.html)
0 Kudos
RichardWatson
Frequent Contributor
I haven't used the ArcGIS Runtime yet but have been using both Silverlight 5 as well as pure Windows applications which consume ArcGIS Server services (including SOE REST extensions).  I use the task framework which is really nice.  In fact, there are a lot of nice things that you can do with the Microsoft framework when you are not bound by all the rules that ArcObjects impose you on.

Unfortunately, I still have alot of ArcObjects code which runs in ArcMap and ArcGIS Server.
0 Kudos
KirkKuykendall
Occasional Contributor III
What if you maintained a collection of backgroundworkers, and when a request comes in, hand it off to the first worker that's not busy?  Logging from the worker (MTA) thread would be reported via ReportProgress. Th STAThread would write to the ServerLogger when the ProgressChanged event fires.

Edit:  On further thought though, doesn't arcgis server already do this when it decides which ArcSoc process to hand the request off to?  In other words, it should know if a mapservice's SOE is busy, and hand the request to one that's not busy, and even wait until one is not busy.
0 Kudos
RichardWatson
Frequent Contributor
Thanks for the suggestion.

What I did was to refactor my code so that I had a class which touched no ArcObjects.  The code used to log warnings (using the ServerLogger) as it ran but I modified it to simply collect this information.  The STA thread which gets the result from the MTA task then logs a summary of all the warnings which occurred, if any.

The thing that I really hate about all of this is having to work around the limitations of ArcObjects.

Also interesting is that I logged an issue with ESRI support with regards the sort order of messages in Server Manager being wrong when you rapidly log messages.  I created a trivial SOE which logged 100 messages in a for loop: "Message 1", "Message 2", etc..  If you sort the server log in reverse order of time then it jumbles the order.  What happens is that chunks of the messages have the same time stamp.  What the code should do is to preserve (or reverse) the order in the file when the timestamps are the same.  Interesting boundary condition.
0 Kudos
KirkKuykendall
Occasional Contributor III
Yes, I've also seen some strange things with logging.

On a multimachine site, if I went into ArcGIS Server Manager and pushed the clear log button, I'd get an error saying it could not complete, or something like that.  Haven't tried it lately. Will try again and post results.

I suspect root cause is that the logger is busy logging a "clearing log" message at the same time it is trying to clear the log.

Is ServerLogger a singleton? If so, did you try using Activator.CreateInstance on the background thread instead of "new"?  (as prescribed by the threads-in-isolation pattern).

From what you describe, it sounds like we should be including our own timestamp in the body of the message.

In general I find SOE's quick and easy, but I can't help but wonder if there are cases where it might make more sense to write a WCF Rest service that uses arcobjects.  These are normally MTAThreaded, but I've read about making it STAThreaded, like here.
0 Kudos