取消锁定对象

时间:2017-02-19 19:24:12

标签: c# multithreading locking cancellation

这可能很简单,但还无法解决。

简单地说:

我的回购图层中有一个长时间运行的操作(大约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),因为我有其他方法可以读取缓存,并且在加载所有缓存之前不应该这样做。

2 个答案:

答案 0 :(得分:0)

无需使用锁来保护8分钟的加载过程,您需要的只是在加载完成后锁定更新缓存集语句。您还应该使用CancellationToken取消加载过程,并在加载过程中定期检查令牌取消状态。

答案 1 :(得分:-1)

使用Monitor.Enter&amp; Monitor.Exit而不是lock,确保捕获异常并释放锁。

示例:

Monitor.Enter(s_cacheLock)

// do work

Monitor.Exit(s_cacheLock)