我刚写了一段代码,然后我发现monitor.wait存在一些问题,迫使我在锁内执行操作,我想现在如果这是保持线程等待的好方法,....
我不确定thread.join是否会完成这项工作,因为我的应用程序中运行了很多线程,并且每个线程都执行特定的工作,它们可能会在时间内终止...
这是我的代码:
public static class TaskManager
{
private static readonly object UpdateLock = new object();
private static readonly object WaitLock = new object();
private static readonly LiaisonDb _db = new LiaisonDb();
private static List<liaQueue> _liaQueueList = new List<liaQueue>();
private static DateTime _lastUpdate = new DateTime();
public static liaQueue GetTask(string sessionType)
{
liaQueue task;
lock (UpdateLock)
{
if (_lastUpdate < DateTime.Now.AddSeconds(-5))
{
Thread t = new Thread(UpdateCache) {IsBackground = true};
t.Start();
lock (WaitLock)
{
Monitor.Wait(WaitLock);
}
_lastUpdate = DateTime.Now;
}
task = _liaQueueList
.FirstOrDefault(w => w.Stat == 0
&& w.Type != null
|| string.Equals(w.Type, sessionType));
}
return task;
}
private static void UpdateCache()
{
try
{
_liaQueueList = _db.liaQueue.Where(w => w.Stat == 0).ToList();
}
finally
{
lock (WaitLock)
{
Monitor.Pulse(WaitLock);
}
}
}
}
如你所见,我放了两个锁,其中一个只用于monitor.wait,让线程等待答案......
我想我还必须在刷新缓存时返回null?...
答案 0 :(得分:2)
来自MSDN
如果两个线程正在使用Pulse和Wait进行交互,则可能导致死锁。
所以,不。您的实施不是最佳做法。
在我看来,GetTask应该更新后台线程上的缓存,然后阻止调用线程直到缓存更新,然后根据选择标准返回第一个任务。
由于调用线程将阻塞(等待)缓存更新,我不太了解首先使用后台线程的意义。 如果目的是防止多个调用线程并行更新缓存,请仅使用lock(UpdateLock)语句。
如果您确实想要在后台线程上运行缓存(并等待它),请考虑使用Task库。但我并没有说明问题。
lock (UpdateLock)
{
if (_lastUpdate < DateTime.Now.AddSeconds(-5)) {
Task.Run(() => {
_liaQueueList = _db.liaQueue.Where(w => w.Stat == 0).ToList();
}).Wait();
_lastUpdate = DateTime.Now;
}
}
return _liaQueueList.FirstOrDefault(w => w.Stat == 0 && w.Type != null || string.Equals(w.Type, sessionType));