Disclaimer. This is perhaps not a best way to do, but I couldn’t find any better way.

Let’s imagine that you have some Task to run in the background. And that task has to update UI for example progress bar. Or that task has to call some callbacks in context of main thread. For firs case you would use Invoke, for second case you would use SynchronizationContext.Send. Implementation is very simple. WinForms will add request to queue of requests and post message to main thread and then it wait on request handle to be signaled. Main thread receives message, processes request and signal on request event. Very simple and quite basic. Post is the same as Send but

In this post I will explain my investigation about handle leaks and how it resulted in interesting discovery in MemoryCache class.

I received few reports stating that our application consuming handles even when it supposed to do nothing. And then I started my investigation. I explained how to find where is leaking handles here.

After application leaked about 50 handles, I paused application and checked call stack. And to my surprise I found a lot of callstack that looks like this:

ntdll!NtCreateThreadEx+0x0000000000000014
KERNELBASE!CreateRemoteThreadEx+0x0000000000000294
KERNELBASE!CreateThread+0x000000000000003b
verifier!AVrfpCreateThread+0x00000000000000bf
clr!Thread::CreateNewOSThread+0x00000000000000b2
clr!Thread::CreateNewThread+0x0000000000000091
clr!ThreadpoolMgr::CreateUnimpersonatedThread+0x00000000000000cb
clr!ThreadpoolMgr::MaybeAddWorkingWorker+0x000000000000011c
clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x0000000000000024
clr!ThreadpoolMgr::SetAppDomainRequestsActive+0x000000000000003f
clr!ThreadPoolNative::RequestWorkerThread+0x000000000000002b
--------------------------------------
ntdll!NtCreateEvent+0x0000000000000014
verifier!AVrfpNtCreateEvent+0x0000000000000080
KERNELBASE!CreateEventW+0x000000000000006b
verifier!AVrfpCreateEventW+0x00000000000000a5
clr!CLREventBase::CreateManualEvent+0x000000000000003a
clr!Thread::AllocHandles+0x000000000000007b
clr!Thread::CreateNewOSThread+0x000000000000007f
clr!Thread::CreateNewThread+0x0000000000000091
clr!ThreadpoolMgr::CreateUnimpersonatedThread+0x00000000000000cb
clr!ThreadpoolMgr::MaybeAddWorkingWorker+0x000000000000011c
clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x0000000000000024
clr!ThreadpoolMgr::SetAppDomainRequestsActive+0x000000000000003f
clr!ThreadPoolNative::RequestWorkerThread+0x000000000000002b
mscorlib_ni!DomainNeutralILStubClass.IL_STUB_PInvoke()$##6000000+0x0000000000000069

From this callstack it wasn’t really obvious what part of

I received few reports stating that our application consuming handles even when it supposed to do nothing. And then I started my investigation. At the beginning I would like to find if it is possible to find handle leaks with some tools. And I immediately found video by Jeff Dailey I believe: https://channel9.msdn.com/Blogs/jeff_dailey/Understanding-handle-leaks-and-how-to-use-htrace-to-find-them who explained how to do it. This video is more than 13 years old. I will explain steps here, because I really hate videos. It is much faster to read than watch.

You need to run C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe and it is usually installed with Debugging Tools and part of Windows SDK. You will see something like this:

Many .NET developers sooner or later will have to do interop with unmanaged world. Let’s say for example that you need to use some Dll written in C++. Passing integers or floats relatively easy, but things are much more complicated with strings. Many C++ Dll still uses ANSI strings, so let’s talk about them. Normally when you read Microsoft documentation you will be slightly confused. Some pages states that you have to use UnmanagedType.LPStr like it stated here: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedtype?view=netframework-4.8#System_Runtime_InteropServices_UnmanagedType_LPStr. And that looks like correct for ANSI strings. Moreover, you can try it and it works just fine.

Some pages stated that you have to use IntPtr: https://docs.microsoft.com/en-us/previous-versions/ms172514(v=vs.100)?redirectedfrom=MSDN and then manually prepare strings to pass

Many developers for Windows used to fact that all resources that you allocated in your application will be released when your process is closed. And in fact, many developers read Windows API function description by diagonal ignoring most of it. Please read it carefully and I will explain why.

Few years ago, developers started to hit the same problem: application failed to start with some stupid unrelated error and in fact all application failed to start again with some strange error. Restart always fixes this problem, so we blamed Microsoft and move on. In some cases, you even cannot restart your PC due to the same strange errors. But we time it start to happen more and more often. And

If you are developer, you should never use anything related to current directory. If you do, then with almost 100% probability you will regret that you did. Let me explain why you should never use it.

Current directory is state of your process. And it is not read only. Some code in your process can change it. And imagine you tested your code and made sure that it is safe to use current directory in that particular place. But tomorrow you or someone in your team will  refactor this code and move it in different part that it is not safe. For example, move that code to function that executes in different thread or threads. Good luck debugging that.

But