Build: eM Client 11.0.1267.0 (Microsoft Store / MSIX), .NET 10 (CoreCLR 10.0.1326), Windows 11 26100, 32 logical cores.
Symptom: after an IMAP fetch on one account stalls and the client gives up, MailClient.exe keeps exactly one CPU core at 100% (≈3.1% in Task Manager on this machine) and never recovers. In our case it ran 52 hours / 187,717 CPU-seconds with no visible error, and the account silently stopped syncing.
Timeline (from eM Client’s own per-account IMAP log):
20:44:57 UID FETCH ... (BODY.PEEK[])for a 168,919-byte message starts20:44:59server starts sendingBODY[] {168919}20:46:04 --- CopyToAsyncWithTimer() timeout— the last line ever written for that account- from ~15 min later, one managed thread is pinned at 100% CPU, continuously, until the process is restarted
Forensics:
- Managed stack (dotnet-stack, 5/5 identical samples):
MailClient.Imap.Base.TransportPipe+<LoggingHandler>d__39.MoveNext()←System.IO.Pipelines.Pipe.AdvanceReader/ReadAsync←System.Threading.Monitor.Enter_Slowpath - Runtime counters while spinning:
dotnet.process.cpu.time = 1.0 s/s,monitor.lock_contentions = 0,gc.collections = 0, allocation ≈25–50 KB/s, thread-pool queue empty ⇒ a pure busy loop — not workload, not GC, not a lock wait. - The dead socket is never closed:
netstatkeeps it in CLOSE_WAIT the whole time (2.5 days here), while the account shows as online but receives nothing.
Expected: when the CopyToAsyncWithTimer() path gives up, the transport pipe and its logging handler should be disposed and the TCP connection closed. A dead stream must not leave a thread spinning.
Notes:
- Per-account IMAP logging is enabled here (
EnableLog=true), and the spinning frame is the logging handler, so this may only be reachable with logging on — but the missing pipe timeout / dispose guard looks like the real issue. - The trigger was a network stall (an idle IMAP connection behind a proxy silently lost its upstream), so the client did nothing wrong at the moment of the stall. What happens afterwards is the bug: no pipe timeout, no dispose, zombie socket, one core burned forever.
Happy to supply more of the trace if that helps.