I've continued working on my program yesterday after a month long break. I didn't change anything on the code but now my application does not start anymore. At one point it just interrupts execution and seems to be stuck in a deadlock, though I'm not sure if it really is a deadlock since it happens when the method returns - at a point where it should normally not happen.
I can't show you the code since it's huge. But I can say surely that the only action beyond it's own thread is access to some UI elements which get invoked by the Dispatcher. And until yesterday everything worked fine, I haven't changed anything there.
This is the place where it happens:
internal override Task InitializeAddIns()
{
try
{
Action action = () => this._addinProvider.InitializeAddins();
Task t = Task.Factory.StartNew(action);
return t;
}
catch (Exception ex)
{
Debugger.Break();
return null;
}
}
Calling code:
// Initialize AddIns
splash.SplashText = "SplashScreen:step_searchAddIns".Translate();
this._addinSystem.InitializeAddIns();
splash.SplashText = "SplashScreen:step_startAddIns".Translate();
await Task.Run(() => this._addinSystem.RunAddins());
// Resolve libraries with NativeCompressor
splash.SplashText = "SplashScreen:step_resolveDependencies".Translate();
The task starts and returns 't'. The InitializeAddins()-method runs successfully to end (checked it with the debugger - logs also show that it finishes completely). The next step is that the declaration line of "action" is marked (as it finished). Then the debugging ends and nothing more happens. Not even this Dispatcher hook gets called:
Dispatcher.CurrentDispatcher.Hooks.DispatcherInactive += (sender, args) => this.Update();
My only assumption is that there's a deadlock somewhere. I can't explain otherwise why the whole execution stops and gets stuck. I just can't find any clue where to start searching. I reworked the newly introduced code and added some extended locking methods which also detect deadlocks. No deadlock detected so far.
Since I don't know what could cause the problem, I tried to use WinDbg and SOSEX to find the error source. Sadly I don't get WinDbg to run. It does check the Symbol server and the last outputs are the following:
CLRDLL: Unable to find mscordacwks_AMD64_x86_4.0.30319.34209.dll by mscorwks search CLRDLL: Unable to find 'SOS_AMD64_x86_4.0.30319.34209.dll' on the path Cannot Automatically load SOS CLRDLL: Loaded DLL mscordacwks_AMD64_x86_4.0.30319.34209.dll CLR DLL status: Loaded DLL mscordacwks_AMD64_x86_4.0.30319.34209.dll
Though it obviously loaded something, I get this message when calling SOSEX's !dlk command:
0:028> !dlk Unable to initialize .NET data interface. Version 4.0.30319.34209 of mscordacwks.dll is required. Locate and load the correct version of mscordacwks.dll. See documentation for the .cordll command. Examining CriticalSections... No deadlocks detected.
So I really don't know any further how to get this bug fixed. What could be reasons for this behaviour? I don't even get an exception. I already enabled CLR exceptions, but not even those get thrown. It's quite strange, I normally would expect that this lockdown does occur somewhere in the middle, not after the method exits...
I found the source of this problem. It was my Splashscreen, a simple Window, which gets accessed by those methods in order to update the current status (which AddIn gets loaded and so on). This was absolutely not threadsafe (I wonder why it worked before...).
I changed it to the following code in all properties. Would be nice if one could check that code and confirm that it is not hacked or a bad approach, since it does look a bit tricky... But it works so far.
public string SplashText
{
get
{
using (ThreadLock.Lock(_lock))
{
return _splashText;
}
}
set
{
if (_dispatcher.CheckAccess())
{
_splashText = value;
OnPropertyChanged();
return;
}
_dispatcher.Invoke(() =>
{
_splashText = value;
OnPropertyChanged();
});
}
}