【发布时间】:2017-02-19 19:24:12
【问题描述】:
这可能很简单,但还无法弄清楚。
简单地说:
我的 repo 层中有一个长时间运行的操作(大约 8 分钟)。
public static ReleaseSelection LoadedReleaseSelection = new ReleaseSelection();
private static object s_cacheLock = new object();
public Long Load(ReleaseSelection releaseSelection)
{
//check if the release passed in to load is different the one previously loaded
if (releaseSelection != LoadedReleaseSelection)
{
//do something to break the lock(s_cacheLock)
}
lock (s_cacheLock)
{
//Reads from TAB files and put them into cache objects.. runs for about 8 mins
LoadedReleaseSelection = releaseSelection;
}
}
服务层异步调用Load
public Task<long> LoadAsync()
{
ReleaseSelection releaseSelection = //get value from db through another repo call
if (releaseSelection == null)
{
return null;
}
return Task.Factory.StartNew(() => m_releaseRepository.Load(releaseSelection));
}
最后,这个服务被一个 API 端点调用
public async Task<IHttpActionResult> ReleaseLoadPost()
{
await m_releaseService.LoadAsync();
return Ok();
}
当以下条件为真时,我如何才能取消 lock(s_cacheLock) 内部加载操作(第一个代码块)
//check if the release passed in to load is different the one previously loaded
if (releaseSelection != LoadedReleaseSelection)
{
//do something to break the lock(s_cacheLock)
}
这样另一个线程就不必等到之前的加载完成了吗?
注意:我需要lock(m_cacheLock),因为我有其他从缓存中读取的方法,并且在加载所有缓存之前真的不应该这样做。
【问题讨论】:
-
将其加载到一个任务中,并使用取消令牌取消上一个任务。这应该会在约 20 毫秒内停止任务,从而跳出锁定语句。
-
你不能“释放”
lock。您可以考虑使用其他同步结构。 -
@ThomasWeller:我似乎不明白我的代码的全部变化,你介意举个例子说明传递取消令牌将如何取消之前的任务吗?
-
@RamiShareef:您的存储库 instances 是否真的在 ASP.NET 调用之间共享?这很不寻常。
-
@StephenCleary 他们不是,在每次调用时我都会得到一个新实例(感谢 IoC)但是,我几乎没有定义为静态的成员来保存有关缓存的信息
标签: c# multithreading locking cancellation