0

Any help with this one greatly appreciated...

I have a WPF application, and I am trying to leverage the Enterprise Library (v5) logging capability to capture certain events. The application is all .Net 4.0.

I have several long running processes, and am using the Task Parallel Library to multithread where necessary. I use the Task.Factory.StartNew syntax, and have several continuations to control flow.

The chain of events finishes with a call to a method I run back on the UI thread, allowing me to udpate various UI components and the like. Wtihin this method I am also trying to write to my log... and the application simply hangs.

To summarise:

1) I have a static 'logging' class to allow me to resolve an instance of the Logger with the usual method:

public static void LogThis(string message)
{    
LogWriter logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
logWriter.Write(message, "My Default Logging Category");
}

2) I have a Task Factory call which kicks off my long running work:

...
var longProcess = Task.Factory.StartNew(() => ThisMethodTakesAWhile(variable));
...

3) This task finishes, via continuation, with a call to my 'wrap things up' method:

... 
// longProcess is the task coming out of the Factory call in point 2.
// We use the Current Sync Context to allow us to come back to the UI thread.
longProcess.ContinueWith(ant => WrapThingsUp(ant.Result), CancellationToken.None, TaskContinuationOptions.NotOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
...

4) My 'wrap things up' method attempts to log:

private void WrapThingsUp(string resultOfLongProcess)
{
//This call locks the applicaiton.
LogThis("Just to let you know I've finished that long task");
// I never get here!
}

My Logging is configured to target a rolling flat file, in a local folder. Any calls from the UI thread work without issue. It seems to ONLY be the calls from out of the TPL that lock.

I have read articles about not being able to write to a single file simultaneously from multiple source (which I am not trying to do, I'm ensuring in point 4 above that nothing else is trying to log).

I have also seen the article here about thread safety, and I wonder if that is related.

EDIT: I've also tried calling the log write explicitly as discussed here, which is pinged in the StackOverflow article here.

EDIT: I'm convinced this is to do with the UI / Dispatcher, as right clicking rapidly on the applications task bar item 'wakes' it up.

If I can add any more detail, please let me know.

Community
  • 1
  • 1
Nick
  • 2,285
  • 2
  • 14
  • 26
  • I would add that I've created a small application to re-create this, and as usual am struggling to do so! The application where the issue arises is much larger, with more TPL usage - I'm assuming that somewhere in that I am not handling the threading or sync context correctly. – Nick Sep 19 '11 at 17:43

1 Answers1

0

First off, use a static constructor to init your static logger, and use a static field to communicate with it. you are wasting a lot of overhead using the factory constntly (it checks the config file every time you log something).

that being said,

I created a simple TPL example that just sleeps for random amounts of time (between 8 and 10 min) before returning to the UI, it sends updates via AsyncOperationManager, to the UI and everything works.

I could not repeat your issue. can you elaborate more ?

using EL 5.0

Mickey Perlstein
  • 2,508
  • 2
  • 30
  • 37
  • My question is somewhat stale now, and in this project we've actually now migrated away from using EL for various reasons. However, I'm accepting this because the advice about the static constructor is valid, as is the description of your example... I'd gone back to creating another mock application after this, and that helped me find some rogue Task chaining that was the cause of the problem I believe. Thanks Mickey. – Nick Nov 07 '12 at 14:14