我有一个带有SQL后端的多用户应用程序。某些关键数据需要在用户之间保持最新,因此我对这些集合类进行了后台刷新。我当前的刷新代码如下。
public virtual bool Refresh()
{
if (SetRefreshThread() == RefreshLockStatus.AlreadyRefreshing) {
DebugLogging("Checking for refresh thread lock", ClassDebugLevel.CollectionRefresh);
if (RefreshLock.WaitOne(5000) == false) {
DebugLogging("Refresh in already in progress on another thread. Aborting refresh");
return false;
} else {
DebugLogging("Finished refreshing on other thread so not refreshing again");
return true;
}
}
DebugLogging("Refresh Starting");
//Refresh code here
DebugLogging("Finished refreshing");
ClearRefreshThread();
return true;
}
protected RefreshLockStatus SetRefreshThread()
{
lock (RefreshSyncLock) {
if (_RefreshThread != null) {
return RefreshLockStatus.AlreadyRefreshing;
}
_RefreshThread = Threading.Thread.CurrentThread;
RefreshLock.Reset();
return RefreshLockStatus.Allowed;
}
}
protected void ClearRefreshThread()
{
lock (RefreshSyncLock) {
_RefreshThread = null;
RefreshLock.Set();
}
}
private readonly Threading.AutoResetEvent RefreshLock = new Threading.AutoResetEvent(true);
当单个线程调用时,这个工作正常,我得到了日志:
2017-07-06 07:13:55.272294 Thread #010 Collection1->Refresh Starting
2017-07-06 07:13:55.323755 Thread #010 Collection1->Finished refreshing
在两个主题上,我也得到了预期的结果:
2017-07-06 07:13:55.272294 Thread #010 Collection1->Refresh Starting
2017-07-06 07:13:55.272294 Thread #011 Collection1->Checking for refresh thread lock
2017-07-06 07:13:55.323755 Thread #010 Collection1->Finished refreshing
2017-07-06 07:13:55.325258 Thread #011 Collection1->Finished refreshing on other thread so not refreshing again
在三个线程上,第三个线程超时而不是在第一个线程
时完成2017-07-06 07:13:55.272294 Thread #010 Collection1->Refresh Starting
2017-07-06 07:13:55.272294 Thread #011 Collection1->Checking for refresh thread lock
2017-07-06 07:13:55.272294 Thread #014 Collection1->Checking for refresh thread lock
2017-07-06 07:13:55.323755 Thread #010 Collection1->Finished refreshing
2017-07-06 07:13:55.325258 Thread #011 Collection1->Finished refreshing on other thread so not refreshing again
2017-07-06 07:14:00.872013 Thread #014 Collection1->Refresh in already in progress on another thread. Aborting refresh
我的目标是,如果刷新在一个线程上启动,并且在执行时,其他线程想要刷新相同的数据,它们都等待第一个线程完成,然后全部返回true。是否有更好的同步对象来实现我想要的目标?
答案 0 :(得分:0)
似乎当同一个WaitOne方法暂停多个线程时,Set方法将允许其中一个线程通过,但不是全部。
由于我的目标是返回就像方法已经完成一样,我只需要在WaitOne之后在分支上添加另一个Set。
public virtual bool Refresh()
{
if (SetRefreshThread() == RefreshLockStatus.AlreadyRefreshing) {
DebugLogging("Checking for refresh thread lock", ClassDebugLevel.CollectionRefresh);
if (RefreshLock.WaitOne(5000) == false) {
DebugLogging("Refresh in already in progress on another thread. Aborting refresh");
return false;
} else {
DebugLogging("Finished refreshing on other thread so not refreshing again");
RefreshLock.Set //Let next thread that is waiting pass
return true;
}
}
DebugLogging("Refresh Starting");
//Refresh code here
DebugLogging("Finished refreshing");
ClearRefreshThread();
return true;
}
这给了我想要的日志
2017-07-07 06:35:28.115506 Thread #011 Collection1->Refresh Starting
2017-07-07 06:35:28.115506 Thread #014 Collection1->Checking for refresh thread lock
2017-07-07 06:35:28.115506 Thread #010 Collection1->Checking for refresh thread lock
2017-07-07 06:35:28.203229 Thread #011 Collection1->Finished refreshing
2017-07-07 06:35:28.204233 Thread #010 Collection1->Finished refreshing on other thread so not refreshing again
2017-07-07 06:35:28.204734 Thread #014 Collection1->Finished refreshing on other thread so not refreshing again