gpt4 book ai didi

c# - 使用调度程序只运行一次代码

转载 作者:太空宇宙 更新时间:2023-11-03 10:38:43 24 4
gpt4 key购买 nike

我有一个只运行一次代码的简单模式。它主要用于在 UI 上更新某些内容,而它可能会在后台经常更改。

private bool _updating;
private void UpdateSomething()
{
if (!_updating)
{
_updating = true;

Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
_updating = false;
DoSomething();
}), DispatcherPriority.Background);
}
}

我更愿意将样板代码放在一个简单的方法中:

public static void RunOnce(Action action, ref bool guard)
{
if (!guard)
{
guard = true;

Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
guard = false;
action();
}), DispatcherPriority.Background);
}
}

可以这样调用它:

void UpdateSomething()
{
RunOnce(DoSomething, ref _updating);
}

但是,这不起作用,因为您不能在匿名方法中使用 ref 参数。有没有解决方法,例如固定 ref 参数并在执行方法时释放它?

最佳答案

你可以这样做:

public static void RunOnce(Action action, ref RunOnceToken token)
{
if (token == null || token.IsCompleted)
{
token = new RunOnceToken(
Application.Current.Dispatcher.BeginInvoke(
action,
DispatcherPriority.Background));
}
}

public sealed class RunOnceToken : IDisposable
{
private DispatcherOperation _operation;

public RunOnceToken(DispatcherOperation operation)
{
if (operation != null &&
operation.Status != DispatcherOperationStatus.Completed &&
operation.Status != DispatcherOperationStatus.Aborted)
{
_operation = operation;
_operation.Completed += OnCompletedOrAborted;
_operation.Aborted += OnCompletedOrAborted;
}
}

private void OnCompletedOrAborted(object sender, EventArgs e)
{
this.Dispose();
}

public bool IsCompleted
{
get { return _operation == null; }
}

public void Dispose()
{
var operation = _operation;
if (operation == null)
return;

_operation = null;

operation.Completed -= OnCompletedOrAborted;
operation.Aborted -= OnCompletedOrAborted;
}
}

您的示例用法将更改为:

private RunOnceToken _updateToken;

private void UpdateSomething()
{
RunOnce(DoSomething, ref _updateToken);
}

如果您从不清除您的 token 副本并不重要,因为包装的 DispatcherOperation 在完成后会被清除以避免泄漏 action 或其任何值捕获。

如果不是很明显,这些都不是并发安全的;我假设以上所有内容只能从 UI 线程访问。

一个有用的增强可能是向 RunOnce 添加一个可选的 DispatcherPriority 参数,这样您就可以控制用于安排 action 的优先级(如果已安排的操作的优先级较低,则可能取消已安排的操作)。

关于c# - 使用调度程序只运行一次代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26385408/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com