我有多个类似于以下的代码块:
void GetPerson(Action<PersonView, Exception> callback);
...
IsBusy = true;
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
IsBusy = false;
});
我遇到的问题是,给定的类可能会触发多个不同的异步调用,并且 IsBusy 属性必须是“智能”的,以免仅仅因为调用“A”已完成而关闭“B”和 'C' 仍然悬而未决。因此 _personRequested 和 _personLoaded bool 值。但是,我想转到更通用的内容,但有点不确定如何进行。
我最初的想法是建立一个接受上述代码作为委托(delegate)的函数,但我一直被奇怪的语法所困扰。我想要这样的功能,这样我就可以简单地包装整个东西并将其作为匿名方法传递给我的函数,然后在该函数和回调中我将处理我的类的忙碌状态。
感谢任何帮助,谢谢。
最佳答案
如果您要查找的只是指示某项正在使用的指示器,那么最好使用计数器而不是简单的 bool 标志。然后,您可以使用 Interlocked.Increment
和 Interlocked.Decrement
以线程安全的方式修改值。
在类级别声明:
private volatile int isBusyCounter;
Interlocked.Increment(ref isBusyCounter);
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
Interlocked.Decrement(ref isBusyCounter);
});
(需要使用 Interlocked
,因为您要在多个线程上修改值,这可确保更新不会相互冲突;我们不关心顺序,因为无论一个先发生还是另一个发生,你最终都会得到相同的值)
然后,不只是检查 IsBusy
,而是检查 IsBusy > 0
。该变量需要是 volatile
以便后续在方法中读取该变量不会被优化掉(换句话说,如果您在循环中检查此条件或在给定的循环中多次检查此条件函数,然后我们将 volatile
放在那里以确保每次都检查该值而不是在本地缓存)。
关于c# - 使用通用委托(delegate) Hook 异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4890840/