第一手,我的应用程序在WPF中。 另一方面,我有一个任务方法来刷新只需要执行一次的某些视图。因此,如果该方法在第一个方法完成之前被第二次调用,它将取消第一个任务方法。
为实现这一目标,我找到了一个通常可以“正常工作”的解决方案,但是有时我会遇到一个例外:“ hwnd不能为IntPtr.Zero或null。”而且我不明白为什么我的第一个解决方案不起作用。
“有效”的解决方案:
private Tuple<Task, CancellationTokenSource> _manageErrorTask;
private void RefreshMyList()
{
if (_manageErrorTask != null && !_manageErrorTask.Item1.IsCompleted)
{
_manageErrorTask.Item2.Cancel();
_manageErrorTask.Item2.Dispose();
_manageErrorTask.Item1.Dispose();
_manageErrorTask = null;
}
var token = new CancellationTokenSource();
CancellationToken ct = token.Token;
ct.Register(() => Console.WriteLine("Cancel Token !! "));
Task task = Task.Run(() =>
{
// Were we already canceled?
if (ct.IsCancellationRequested) return;
try
{
foreach (var userControl in MyList)
{
RT(() =>
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
var vm = userControl.DataContext as ViewModelBase;
vm?.Refresh("yololo");
}));
},
ct);
}
}
catch(Exception e)
{
//Do nothing
}
}, ct);
_manageErrorTask = Tuple.Create(task, token);
}
public static void RT(Action action, CancellationToken token)
{
if (action == null)
return;
Task.Run(async () => {
if (!token.IsCancellationRequested)
{
action();
}
}, token);
}
我的解决方案无效:
private Tuple<Task, CancellationTokenSource> _manageErrorTask;
private void RefreshMyList()
{
if (_manageErrorTask != null && !_manageErrorTask.Item1.IsCompleted)
{
_manageErrorTask.Item2.Cancel();
_manageErrorTask.Item2.Dispose();
_manageErrorTask.Item1.Dispose();
_manageErrorTask = null;
}
var token = new CancellationTokenSource();
CancellationToken ct = token.Token;
ct.Register(() => Console.WriteLine("Cancel Token !! "));
Task task = Task.Run(() =>
{
// Were we already canceled?
if (ct.IsCancellationRequested) return;
try
{
foreach (var userControl in MyList)
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
var vm = userControl.DataContext as ViewModelBase;
vm?.Refresh("yololo");
ct.ThrowIfCancellationRequested();
}));
}
}
catch(Exception e)
{
//Do nothing
}
},
ct);
_manageErrorTask = Tuple.Create(task, token);
}