通过 RunAsync 自动使 Service Fabric Reliable Dictionary 对象过期
Automatically expire Service Fabric Reliable Dictionary objects via RunAsync
我正在尝试将自动删除添加到过期的可靠字典对象中,看起来我必须根据这个实现我自己的方式:
我的方法是使用 "RunAsync" 任务并使其不断 运行 一个 while 循环。它在前几次有效,但在我向字典中添加了更多对象后出现了一个奇怪的错误。这是一种愚蠢的做法吗?其他人如何自动清除他们可靠的字典对象?
protected override async Task RunAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
await deleteExpired("MyDictionaryName", cancellationToken);
}
}
private async Task deleteExpired(string dictionaryName, CancellationToken cancellationToken)
{
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, CacheObject>>(dictionaryName);
Dictionary<string, CacheObject> ret = new Dictionary<string, CacheObject>();
using (var tx = StateManager.CreateTransaction())
{
var count = myDictionary.GetCountAsync(tx);
if (count.Result > 0)
{
IAsyncEnumerator<KeyValuePair<string, CacheObject>> e = (await myDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();
while (await e.MoveNextAsync(cancellationToken))
{
if (e.Current.Value.expiration <= DateTime.Now)
{
await myDictionary.TryRemoveAsync(tx, e.Current.Key);
await tx.CommitAsync();
ServiceEventSource.Current.ServiceMessage(this.Context, String.Format("Object deleted at {0} - key: {1} expired at {2}", DateTime.Now.ToString(), e.Current.Key, e.Current.Value.expiration.ToString()));
}
}
}
}
}
错误:
在我向字典中添加了一些可靠的字典对象后,"while(true)" 发生了错误。
托管调试助手 'FatalExecutionEngineError' 在 'C:\SfDevCluster\Data_App_Node_2\CacheApplicationType_App339\CachePkg.Code.1.0.0\Cache.exe' 中检测到问题。
附加信息:运行时遇到致命错误。错误地址位于线程 0x1980 上的 0x8c46ed90。错误代码是 0x80131623。此错误可能是 CLR 中的错误,或者是用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户编组错误,这可能会损坏堆栈。
如果Reliable Dictionary 包含多个准备过期的项目,上述代码在事务终止后继续使用该事务(在上述情况下已提交)。这会在枚举中产生一个断言,因为它是在它绑定到的事务终止后使用的。
我会把Reliable Collections中的推荐更新为
- 在用于创建的事务终止 (committed/aborted) 或处置后不要使用枚举。
我正在尝试将自动删除添加到过期的可靠字典对象中,看起来我必须根据这个实现我自己的方式:
我的方法是使用 "RunAsync" 任务并使其不断 运行 一个 while 循环。它在前几次有效,但在我向字典中添加了更多对象后出现了一个奇怪的错误。这是一种愚蠢的做法吗?其他人如何自动清除他们可靠的字典对象?
protected override async Task RunAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
await deleteExpired("MyDictionaryName", cancellationToken);
}
}
private async Task deleteExpired(string dictionaryName, CancellationToken cancellationToken)
{
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, CacheObject>>(dictionaryName);
Dictionary<string, CacheObject> ret = new Dictionary<string, CacheObject>();
using (var tx = StateManager.CreateTransaction())
{
var count = myDictionary.GetCountAsync(tx);
if (count.Result > 0)
{
IAsyncEnumerator<KeyValuePair<string, CacheObject>> e = (await myDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();
while (await e.MoveNextAsync(cancellationToken))
{
if (e.Current.Value.expiration <= DateTime.Now)
{
await myDictionary.TryRemoveAsync(tx, e.Current.Key);
await tx.CommitAsync();
ServiceEventSource.Current.ServiceMessage(this.Context, String.Format("Object deleted at {0} - key: {1} expired at {2}", DateTime.Now.ToString(), e.Current.Key, e.Current.Value.expiration.ToString()));
}
}
}
}
}
错误: 在我向字典中添加了一些可靠的字典对象后,"while(true)" 发生了错误。
托管调试助手 'FatalExecutionEngineError' 在 'C:\SfDevCluster\Data_App_Node_2\CacheApplicationType_App339\CachePkg.Code.1.0.0\Cache.exe' 中检测到问题。
附加信息:运行时遇到致命错误。错误地址位于线程 0x1980 上的 0x8c46ed90。错误代码是 0x80131623。此错误可能是 CLR 中的错误,或者是用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户编组错误,这可能会损坏堆栈。
如果Reliable Dictionary 包含多个准备过期的项目,上述代码在事务终止后继续使用该事务(在上述情况下已提交)。这会在枚举中产生一个断言,因为它是在它绑定到的事务终止后使用的。
我会把Reliable Collections中的推荐更新为
- 在用于创建的事务终止 (committed/aborted) 或处置后不要使用枚举。