I am executing the async Task in my window:
private async Task LoadData()
{
// Fetch data
var data = await FetchData();
// Display data
// ...
}
The window is launched in separate thread:
// Create and run new thread
var thread = new Thread(ThreadMain);
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
thread.CurrentUICulture = Thread.CurrentThread.CurrentUICulture;
thread.Start();
private static void ThreadMain()
{
// Set synchronization context
var dispatcher = Dispatcher.CurrentDispatcher;
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(dispatcher));
// Show window
var window = new MyWindow();
window.ShowDialog();
// Shutdown
dispatcher.InvokeShutdown();
}
When the windows is closed, the thread is of course finished, which is just fine.
Now - if that happens before the FetchData
is finished, I get the memory leak.
Appears that FetchData
remains awaited forever and the Task.s_currentActiveTasks
static field is retaining my window instance forever:
Retention path
System.Collections.Generic.Dictionary.entries -> System.Collections.Generic.Dictionary+Entry[37] at [17].value -> System.Threading.Tasks.Task.m_continuationObject -> System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.m_action -> System.Action._target -> System.Runtime.CompilerServices.AsyncMethodBuilderCore+ContinuationWrapper.m_continuation -> System.Action._target -> System.Runtime.CompilerServices.AsyncMethodBuilderCore+ContinuationWrapper.m_continuation -> System.Action._target -> ...
If I understand this correctly, if/when the FetchData
completes, the continuation should continue on the window instance target and a thread, but that never happens since the thread is finished.
Is there any solutions to this, how to avoid memory leak in this case?