Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
68950d0f
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
68950d0f
编写于
6月 15, 2020
作者:
A
Allison Chou
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Switch to time-based batching
上级
97e27fdd
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
22 addition
and
43 deletion
+22
-43
src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs
...ageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs
+22
-43
未找到文件。
src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs
浏览文件 @
68950d0f
...
...
@@ -27,8 +27,6 @@ namespace Microsoft.CodeAnalysis.LanguageServer.CustomProtocol
{
internal
class
FindUsagesLSPContext
:
FindUsagesContext
{
private
const
int
MaxResultsChunkSize
=
32
;
private
readonly
IProgress
<
object
[
]>
_progress
;
private
readonly
Document
_document
;
private
readonly
int
_position
;
...
...
@@ -37,7 +35,7 @@ internal class FindUsagesLSPContext : FindUsagesContext
/// <summary>
/// Methods in FindUsagesLSPContext can be called by multiple threads concurrently.
/// We need this sempahore to ensure that we aren't making concurrent
/// modifications to data such as _id
, _definitionToId, and _resultsChunk
.
/// modifications to data such as _id
and _definitionToId
.
/// </summary>
private
readonly
SemaphoreSlim
_semaphore
=
new
SemaphoreSlim
(
1
);
...
...
@@ -51,8 +49,10 @@ internal class FindUsagesLSPContext : FindUsagesContext
private
readonly
Dictionary
<
int
,
VSReferenceItem
>
_definitionsWithoutReference
=
new
Dictionary
<
int
,
VSReferenceItem
>();
private
readonly
List
<
VSReferenceItem
>
_resultsChunk
=
new
List
<
VSReferenceItem
>();
/// <summary>
/// We report the results in chunks. A batch, if it contains results, is reported every 0.5s.
/// </summary>
private
readonly
AsyncBatchingWorkQueue
<
VSReferenceItem
>
_workQueue
;
// Unique identifier given to each definition and reference.
private
int
_id
=
0
;
...
...
@@ -70,31 +70,22 @@ internal class FindUsagesLSPContext : FindUsagesContext
_document
=
document
;
_position
=
position
;
_metadataAsSourceFileService
=
metadataAsSourceFileService
;
_workQueue
=
new
AsyncBatchingWorkQueue
<
VSReferenceItem
>(
TimeSpan
.
FromSeconds
(
0.5
),
ReportIfNotEmptyAsync
,
cancellationToken
);
CancellationToken
=
cancellationToken
;
}
public
override
async
Task
OnCompletedAsync
()
public
override
Task
OnCompletedAsync
()
{
using
var
_
=
ArrayBuilder
<
VSReferenceItem
>.
GetInstance
(
out
var
referencesToReport
);
using
(
await
_semaphore
.
DisposableWaitAsync
(
CancellationToken
).
ConfigureAwait
(
false
))
{
if
(
_resultsChunk
.
IsEmpty
())
{
return
;
}
referencesToReport
.
AddRange
(
_resultsChunk
);
_resultsChunk
.
Clear
();
}
// We can report outside of the lock here since _progress is thread-safe.
_progress
.
Report
(
referencesToReport
.
ToArray
());
// Upon completion, we wait an additional 0.5s (the time in between batches) to ensure
// that all results have been reported.
Thread
.
Sleep
(
500
);
return
Task
.
CompletedTask
;
}
public
override
async
Task
OnDefinitionFoundAsync
(
DefinitionItem
definition
)
{
using
var
_
=
ArrayBuilder
<
VSReferenceItem
>.
GetInstance
(
out
var
referencesToReport
);
using
(
await
_semaphore
.
DisposableWaitAsync
(
CancellationToken
).
ConfigureAwait
(
false
))
{
if
(
_definitionToId
.
ContainsKey
(
definition
))
...
...
@@ -118,7 +109,7 @@ public override async Task OnDefinitionFoundAsync(DefinitionItem definition)
// have to hold off on reporting it until later when we do find a reference.
if
(
definition
.
DisplayIfNoReferences
)
{
AddToReferencesToReport_MustBeCalledUnderLock
(
referencesToReport
,
definitionItem
);
AddToReferencesToReport_MustBeCalledUnderLock
(
definitionItem
);
}
else
{
...
...
@@ -126,13 +117,10 @@ public override async Task OnDefinitionFoundAsync(DefinitionItem definition)
}
}
}
ReportIfNotEmpty
(
referencesToReport
);
}
public
override
async
Task
OnReferenceFoundAsync
(
SourceReferenceItem
reference
)
{
using
var
_
=
ArrayBuilder
<
VSReferenceItem
>.
GetInstance
(
out
var
referencesToReport
);
using
(
await
_semaphore
.
DisposableWaitAsync
(
CancellationToken
).
ConfigureAwait
(
false
))
{
// Each reference should be associated with a definition. If this somehow isn't the
...
...
@@ -145,7 +133,7 @@ public override async Task OnReferenceFoundAsync(SourceReferenceItem reference)
// If the definition hasn't been reported yet, add it to our list of references to report.
if
(
_definitionsWithoutReference
.
TryGetValue
(
definitionId
,
out
var
definition
))
{
AddToReferencesToReport_MustBeCalledUnderLock
(
referencesToReport
,
definition
);
AddToReferencesToReport_MustBeCalledUnderLock
(
definition
);
_definitionsWithoutReference
.
Remove
(
definitionId
);
}
...
...
@@ -159,25 +147,15 @@ public override async Task OnReferenceFoundAsync(SourceReferenceItem reference)
if
(
referenceItem
!=
null
)
{
AddToReferencesToReport_MustBeCalledUnderLock
(
reference
sToReport
,
reference
Item
);
AddToReferencesToReport_MustBeCalledUnderLock
(
referenceItem
);
}
}
ReportIfNotEmpty
(
referencesToReport
);
}
private
void
AddToReferencesToReport_MustBeCalledUnderLock
(
ArrayBuilder
<
VSReferenceItem
>
referencesToReport
,
VSReferenceItem
item
)
private
void
AddToReferencesToReport_MustBeCalledUnderLock
(
VSReferenceItem
item
)
{
Debug
.
Assert
(
_semaphore
.
CurrentCount
==
0
);
_resultsChunk
.
Add
(
item
);
if
(
_resultsChunk
.
Count
<
MaxResultsChunkSize
)
{
return
;
}
referencesToReport
.
AddRange
(
_resultsChunk
);
_resultsChunk
.
Clear
();
_workQueue
.
AddWork
(
item
);
}
private
static
async
Task
<
LSP
.
VSReferenceItem
?>
GenerateVSReferenceItemAsync
(
...
...
@@ -219,7 +197,7 @@ private void AddToReferencesToReport_MustBeCalledUnderLock(ArrayBuilder<VSRefere
DisplayPath
=
location
.
Uri
.
LocalPath
,
DocumentName
=
documentSpan
==
default
?
null
:
documentSpan
.
Document
.
Name
,
Id
=
id
,
Kind
=
symbolUsageInfo
.
HasValue
?
ProtocolConversions
.
SymbolUsageInfoToReferenceKinds
(
symbolUsageInfo
.
Value
)
:
new
ReferenceKind
[]
{
}
,
Kind
=
symbolUsageInfo
.
HasValue
?
ProtocolConversions
.
SymbolUsageInfoToReferenceKinds
(
symbolUsageInfo
.
Value
)
:
Array
.
Empty
<
ReferenceKind
>()
,
Location
=
location
,
ProjectName
=
documentSpan
==
default
?
null
:
documentSpan
.
Document
.
Project
.
Name
,
ResolutionStatus
=
ResolutionStatusKind
.
ConfirmedAsReference
,
...
...
@@ -299,15 +277,16 @@ private void AddToReferencesToReport_MustBeCalledUnderLock(ArrayBuilder<VSRefere
}
}
private
void
ReportIfNotEmpty
(
ArrayBuilder
<
VSReferenceItem
>
referencesToReport
)
private
Task
ReportIfNotEmptyAsync
(
ImmutableArray
<
VSReferenceItem
>
referencesToReport
,
CancellationToken
cancellationToken
)
{
if
(
referencesToReport
.
IsEmpty
()
)
if
(
referencesToReport
.
IsEmpty
)
{
return
;
return
Task
.
CompletedTask
;
}
// We can report outside of the lock here since _progress is thread-safe.
_progress
.
Report
(
referencesToReport
.
ToArray
());
return
Task
.
CompletedTask
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录