C# 运行后台任务,直到对象超出范围

C# 运行后台任务,直到对象超出范围,c#,task-parallel-library,C#,Task Parallel Library,我想实现一个运行后台任务的类,循环并更新该类的状态。一旦类超出范围,运行后台任务就没有任何价值,因此我想退出循环,允许任务完成并释放线程 public class ValueProvider { private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken(); public string Value {get; private set;} public IChangeToke

我想实现一个运行后台任务的类,循环并更新该类的状态。一旦类超出范围,运行后台任务就没有任何价值,因此我想退出循环,允许任务完成并释放线程

public class ValueProvider
{
    private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();

    public string Value {get; private set;}

    public IChangeToken ChangeToken => _reloadToken;

    public void Load()
    {
        // Load the initial value.
        Value = "Foo";            

        // Watch for changes to and reload the value.
        WatchForChanges();
    }

    private void WatchForChanges() => Task.Run(WatchAsync);

    private async Task WatchAsync()
    {   
        var stillInScope = true;
        while(stillInScope)
        {
            // Watch for new values.
            Value = await LoadNewValueAsync();

            // Signal a change.
            OnReload();
        }
    }

    private async Task<string> LoadNewValueAsync()
    {
        // Simulate an actual lookup which blocks until a new value is available.
        await Task.Delay(TimeSpan.FromSeconds(30));

        return "Bar";
    }

    private void OnReload()
    {
        var previousToken = Interlocked.Exchange(
            ref _reloadToken,
            new ConfigurationReloadToken());
        previousToken.OnReload();
    }
}
公共类ValueProvider
{
私有ConfigurationReloadToken _reloadToken=new ConfigurationReloadToken();
公共字符串值{get;private set;}
公共IChangeToken ChangeToken=>\u重新加载Token;
公共空荷载()
{
//加载初始值。
Value=“Foo”;
//观察并重新加载值的更改。
WatchForChanges();
}
私有void WatchForChanges()=>Task.Run(WatchAsync);
专用异步任务WatchAsync()
{   
var stillInScope=真;
while(静止镜)
{
//关注新的价值观。
Value=wait LoadNewValueAsync();
//发出改变的信号。
OnReload();
}
}
专用异步任务LoadNewValueAsync()
{
//模拟实际查找,直到新值可用为止。
等待任务延迟(时间跨度从秒(30));
返回“Bar”;
}
私有void OnReload()
{
var-previousToken=联锁的.Exchange(
参考重新加载令牌,
新的ConfigurationReloadToken());
previousToken.OnReload();
}
}
由于创建的
任务
引用了
值提供程序
,因此实例永远不会超出范围。解决方案可能必须包括通过
WeakReference
从后台任务访问
ValueProvider
,以使其超出范围,但我对解决方案持开放态度


如何检测“前台”对象已超出范围并停止伴随的后台任务?

By
已超出范围
您的意思是
有资格进行垃圾收集
?或者
已被垃圾收集
?或者别的什么?如果它可以与“using”指令一起使用,您可以实现一次性模式…@mjwills我在技术上的意思是“有资格进行垃圾收集”,但这有点微妙;我的意思是“除后台任务外,任何对象都无法访问”。@Fildor我通常会使用
IDisposable
进行此类清理,但我没有确定的范围。使用
WeakReference
(这是此类型问题的常见解决方案)有什么关系?