如何在方法完成执行之前返回数据?

时间:2015-12-08 13:04:31

标签: c# multithreading

我有一个缓慢且昂贵的方法可以为我返回一些数据:

public Data GetData(){...}

我不想等到这个方法执行。而不是我想立即返回缓存数据。

我有一个类CachedData,其中包含一个属性Data cachedData。 所以我想创建另一个方法public CachedData GetCachedData(),它将启动一个新任务(在其中调用GetData)并立即返回缓存数据,在任务完成后我们将更新缓存。

我需要线程安全GetCachedData(),因为我将有多个请求将调用此方法。

我会点亮一下“有什么变化吗?”每分钟,如果它将返回true(cachedData!= currentData),那么我将调用GetCachedData()

我是C#的新人。请帮我实现这个方法。

我正在使用.net framework 4.5.2

3 个答案:

答案 0 :(得分:2)

基本理念很明确:

  • 你有一个Data属性,它包含了一个昂贵的函数调用。
  • 为了立即拥有某些响应,该属性包含缓存值并在后台执行更新。
  • 因为您现在轮询更新器,因此无需事件。

这似乎是一个直截了当的设计。在某些时候,您可能希望使用事件,但可以在以后添加。

根据具体情况,可能需要对属性进行线程安全访问。我认为如果Data缓存是一个简单的引用而没有其他数据与它一起更新,则不需要锁定,但是您可能希望声明引用volatile以便读取线程执行不依赖陈旧的缓存(哈!)版本。 This post似乎有很好的联系来讨论这些问题。

答案 1 :(得分:1)

如果您不会同时调用GetCachedData,则可能无法使用锁定。如果数据为空(肯定是第一次运行),我们将等待很长时间的方法来完成它的工作。

public class SlowClass
{
    private static object _lock;
    private static Data _cachedData;
    public SlowClass()
    {
        _lock = new object();
    }

    public void GetCachedData()
    {
        var task = new Task(DoStuffLongRun);
        task.Start();
        if (_cachedData == null)
            task.Wait();
    }

    public Data GetData()
    {
        if (_cachedData == null)
            GetCachedData();
        return _cachedData;
    }
    private void DoStuffLongRun()
    {

        lock (_lock)
        {
            Console.WriteLine("Locked Entered");
            Thread.Sleep(5000);//Do Long Stuff
            _cachedData = new Data();
        }

    }
}

我已在控制台应用程序上测试过。

 static void Main(string[] args)
    {

        var mySlow = new SlowClass();
        var mySlow2 = new SlowClass();
        mySlow.GetCachedData();
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(i);
            mySlow.GetData();
            mySlow2.GetData();
        }
        mySlow.GetCachedData();
        Console.Read();
    }

答案 2 :(得分:-1)

也许你可以使用MemoryCache类, 正如here in MSDN

所解释的那样