I have a Task
that queries an active directory and populates a list with the results. I have set up my task so that it can be cancelled, however, when the cancel is invoked, the task keeps performing its work. I know the task has been cancelled, as it returns and the actions intended to be performed on task return are run, but the query keeps running in the background, using memory and processing power. The task can be started and "cancelled" repeatedly, with each iteration of the task running and using resources. How can I make the cancel actually cancel?
ViewModel
private async Task RunQuery(QueryType queryType,
string selectedItemDistinguishedName = null)
{
StartTask();
try
{
_activeDirectoryQuery = new ActiveDirectoryQuery(queryType,
CurrentScope, selectedItemDistinguishedName);
await _activeDirectoryQuery.Execute();
Data = _activeDirectoryQuery.Data.ToDataTable().AsDataView();
CurrentQueryType = queryType;
}
catch (ArgumentNullException)
{
ShowMessage(
"No results of desired type found in selected context.");
}
catch (OutOfMemoryException)
{
ShowMessage("The selected query is too large to run.");
}
FinishTask();
}
private void CancelCommandExecute()
{
_activeDirectoryQuery?.Cancel();
}
ActiveDirectoryQuery
public async Task Execute()
{
_cancellationTokenSource = new CancellationTokenSource();
var taskCompletionSource = new TaskCompletionSource<object>();
_cancellationTokenSource.Token.Register(
() => taskCompletionSource.TrySetCanceled());
DataPreparer dataPreparer = null;
var task = Task.Run(() =>
{
if (QueryTypeIsOu())
{
dataPreparer = SetUpOuDataPreparer();
}
else if (QueryTypeIsContextComputer())
{
dataPreparer = SetUpComputerDataPreparer();
}
else if (QueryTypeIsContextDirectReportOrUser())
{
dataPreparer = SetUpDirectReportOrUserDataPreparer();
}
else if (QueryTypeIsContextGroup())
{
dataPreparer = SetUpGroupDataPreparer();
}
Data = GetData(dataPreparer);
},
_cancellationTokenSource.Token);
await Task.WhenAny(task, taskCompletionSource.Task);
}
public void Cancel()
{
_cancellationTokenSource?.Cancel();
}
Cancel()
is called by a Command
that is bound to a Button
. The task can take several minutes to execute and can consume several hundred megabytes of RAM. If it would help, I can provide any of the referenced methods or any other information.