/// <summary> /// 如果当前节点处于 <see cref="FetchingStatus.Fetching"/> 状态, /// 则尝试将节点置于 <see cref="FetchingStatus.Fetched" /> 状态。 /// </summary> public void MarkAsFetched(FetchingDomainKey domainKey) { if (domainKey == null) { throw new ArgumentNullException(nameof(domainKey)); } syncLock.EnterWriteLock(); try { Debug.Assert(fetchingStatusDict[domainKey] == FetchingStatus.Fetching); fetchingStatusDict[domainKey] = FetchingStatus.Fetched; Debug.WriteLine("Fetched-{0}: {1} @ {2}", domainKey, this, Task.CurrentId); var tcs = fetchingTaskCompletionSourceDict.TryGetValue(domainKey); if (tcs != null) { // 为什么是 true ? // 参阅 explorationTaskCompletionSourceDict 声明处的约定。 tcs.SetResult(true); fetchingTaskCompletionSourceDict.Remove(domainKey); } } finally { syncLock.ExitWriteLock(); } }
/// <summary> /// 如果当前节点处于 <see cref="FetchingStatus.Fetching"/> 状态, /// 则等待直到节点处于 <see cref="FetchingStatus.Fetched" /> 状态。 /// </summary> /// <returns> /// 返回一个任务。如果当前节点处于 <see cref="FetchingStatus.Unfetched"/> /// 状态,则直接返回 false 。 /// 否则会在(其他线程)探索结束后返回 <c>true</c>。 /// </returns> public Task <bool> UntilFetchedAsync(FetchingDomainKey domainKey) { if (domainKey == null) { throw new ArgumentNullException(nameof(domainKey)); } syncLock.EnterWriteLock(); try { FetchingStatus s; if (fetchingStatusDict.TryGetValue(domainKey, out s)) { switch (s) { case FetchingStatus.Fetching: // Wait for exploration Debug.WriteLine("Wait-{0}: {1} @ {2}", domainKey, this, Task.CurrentId); var tcs = fetchingTaskCompletionSourceDict.GetOrAddNew(domainKey); return(tcs.Task.ContinueWith(r => true)); case FetchingStatus.Fetched: return(Task.FromResult(true)); default: Debug.Assert(s == FetchingStatus.Unfetched); break; } } return(Task.FromResult(false)); } finally { syncLock.ExitWriteLock(); } }
/// <summary> /// 如果当前节点处于 <see cref="FetchingStatus.Unfetched"/> 状态, /// 则尝试将节点置于 <see cref="FetchingStatus.Fetching" /> 状态。 /// </summary> /// <param name="domainKey"> /// 对此节点注册一个标志。用于表示此节点的某些关联 /// (如作者的所有论文,或是一篇文章的所有引用) /// 已经被探索。 /// </param> /// <returns> /// 如果成功将节点置于 <see cref="FetchingStatus.Fetching" /> 状态, /// 则返回 true 。指示当前线程应当开始探索对应的节点。 /// </returns> public bool TryMarkAsFetching(FetchingDomainKey domainKey) { if (domainKey == null) { throw new ArgumentNullException(nameof(domainKey)); } syncLock.EnterWriteLock(); try { FetchingStatus s; if (fetchingStatusDict.TryGetValue(domainKey, out s)) { if (s != FetchingStatus.Unfetched) { return(false); } } fetchingStatusDict[domainKey] = FetchingStatus.Fetching; Debug.WriteLine("Fetching-{0}: {1} @ {2}", domainKey, this, Task.CurrentId); return(true); } finally { syncLock.ExitWriteLock(); } }
/// <summary> /// 将当前节点标注为 <see cref="FetchingStatus.Fetching" /> 状态。 /// 如果当前节点已经处于 <see cref="FetchingStatus.Fetching" /> 状态, /// 则会等待直到节点处于 <see cref="FetchingStatus.Fetched" /> 状态。 /// </summary> /// <param name="domainKey"></param> /// <returns> /// 如果成功将节点置于 <see cref="FetchingStatus.Fetching" /> 状态, /// 则任务会返回 true 。指示当前线程应当开始探索对应的节点。否则,如果当前节点 /// 已经被探索,或正在探索,则任务会在探索结束后返回 false 。 /// </returns> public Task <bool> MarkAsFetchingOrUntilFetched(FetchingDomainKey domainKey) { if (TryMarkAsFetching(domainKey)) { return(Task.FromResult(true)); } return(UntilFetchedAsync(domainKey).ContinueWith(t => false)); }
public FetchingStatus GetFetchingStatus(FetchingDomainKey domainKey) { if (domainKey == null) { throw new ArgumentNullException(nameof(domainKey)); } syncLock.EnterReadLock(); try { FetchingStatus s; if (fetchingStatusDict.TryGetValue(domainKey, out s)) { return(s); } return(FetchingStatus.Unfetched); } finally { syncLock.ExitReadLock(); } }
protected override bool EqualsCore(FetchingDomainKey other) { return(base.EqualsCore(other) && AnotherNodeId == ((InterceptionFetchingDomainKey)other).AnotherNodeId); }
protected override bool EqualsCore(FetchingDomainKey other) { return(base.EqualsCore(other) && Name == ((TokenFetchingDomainKey)other).Name); }