将双重空检查与任务相结合

时间:2013-08-13 18:17:10

标签: c# .net asynchronous .net-4.0

这是我所拥有的代码的同步版本(非常简化,但它证明了这一点):

private IDictionary<string, string> m_map;
private readonly object m_lock = new object();

private IDictionary<string, string> ConstructTheMap() { ... }

public string MapString(string key)
{
  if (m_map == null)
  {
    lock (m_lock)
    {
      if (m_map == null)
      {
        m_map = ConstructTheMap();
      }
    }
  }
  return m_map[key];
}

现在我想重写它以异步工作。这是我能想到的最好的:

private volatile TaskCompletionSource<IDictionary<string, string>> m_mapTaskCompletionSource;
private readonly object m_lock = new object();

private Task<IDictionary<string, string>> ConstructTheMapAsync() { ... }

public Task<string> MapString(string key)
{
  if (m_mapTaskCompletionSource == null)
  {
    lock (m_lock)
    {
      if (m_mapTaskCompletionSource == null)
      {
        m_mapTaskCompletionSource = new TaskCompletionSource<IDictionary<string, string>>();
        try
        {
          return ConstructTheMapAsync().ContinueWith(t =>
          {
            if (t.Exception != null)
            {
              m_mapTaskCompletionSource.SetException(t.Exception);
              // fall through, will fail anyway when trying to access the result
            }

            m_mapTaskCompletionSource.SetResult(t.Result);

            return t.Result[key];
          });
        }
        catch (Exception exc)
        {
          m_mapTaskCompletionSource.SetException(exc);
          throw;
        }
      }
    }
  }

  return m_mapTaskCompletionSource.Task.ContinueWith(t => t.Result[key]);
}

我仅限于.NET 4.0,没有任何选项可以安装the extension,允许使用async关键字。

无论如何,我觉得如果没有async关键字,它可以写得更好,更紧凑。有什么想法吗?

0 个答案:

没有答案