我有使用 await 关键字异步调用的函数:
public Task<StatePropertyEx> RequestStateForEntity(EntityKey entity, string propName)
{
var tcs = new TaskCompletionSource<StateInfo>();
try
{
var propInstance = BuildCacheKey(entity, propName);
StateCacheItem cacheItem;
if (_stateCache.TryGetValue(propInstance, out cacheItem))
{
tcs.SetResult( new StateInfo (cacheItem.State.Name, cacheItem.State.Value) );
return tcs.Task;
}
//state not found in local cache so save the tcs for later and request the state
var cacheKey = BuildCacheKey(entity, propName);
_stateRequestItemList.TryAdd(cacheKey, new StateRequestItem(entity, propName, tcs));
_evtClient.SubmitStateRequest(entity, propName);
return tcs.Task;
}
catch (Exception ex)
{
tcs.SetException(ex);
return tcs.Task;
}
}
该函数查看它是否具有所需的信息,如果有,则返回它。如果它没有详细信息,它会发送一个请求,该请求最终应该作为一个事件出现。此时我的代码(未显示)找到存储的 TaskCompletionSource 项,设置结果并返回它。这一切都很好,但我现在被要求考虑当我通过“_evtClient.SubmitStateRequest(entity, propName);”请求状态时可能永远不会返回回复的情况。线。我需要实现某种超时机制,以便我可以取消 TCS 任务,以便函数调用者可以正常失败。我一直在寻找 SO 和互联网,找不到任何看起来正确的东西。我现在不确定是否需要以不同的方式重组上述代码。任何人都可以建议或指出类似的情况吗?
调用上述函数的代码可以像这样一次性调用它:
var stateProperty = await RequestStateForEntity(key, stateName);
或分批,像这样:
await
Task.WhenAll(
stateDefinitions.Select(stateDefinition => stateDefinition.Name)
.Select(
stateName =>
Task.Factory.StartNew(
async () => results.Add(await RequestStateForEntity(key, stateName)))
.Unwrap())
.ToArray());