Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
b76fac9e
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,发现更多精彩内容 >>
未验证
提交
b76fac9e
编写于
6月 10, 2019
作者:
S
Sam Harwell
提交者:
GitHub
6月 10, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #36129 from sharwell/writes-no-capture
Avoid captures in SqlConnection.FlushSpecificWritesAsync
上级
d4878317
3a6e02c8
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
44 addition
and
41 deletion
+44
-41
src/Workspaces/Core/Portable/Storage/SQLite/SQLitePersistentStorage_WriteBatching.cs
...e/Storage/SQLite/SQLitePersistentStorage_WriteBatching.cs
+44
-41
未找到文件。
src/Workspaces/Core/Portable/Storage/SQLite/SQLitePersistentStorage_WriteBatching.cs
浏览文件 @
b76fac9e
...
...
@@ -67,6 +67,7 @@ internal partial class SQLitePersistentStorage
}
}
[
PerformanceSensitive
(
"https://github.com/dotnet/roslyn/issues/36114"
,
AllowCaptures
=
false
)]
private
async
Task
FlushSpecificWritesAsync
<
TKey
>(
MultiDictionary
<
TKey
,
Action
<
SqlConnection
>>
keyToWriteActions
,
Dictionary
<
TKey
,
Task
>
keyToWriteTask
,
...
...
@@ -77,7 +78,7 @@ internal partial class SQLitePersistentStorage
// Get's the task representing the current writes being performed by another
// thread for this queue+key, and a TaskCompletionSource we can use to let
// other threads know about our own progress writing any new writes in this queue.
var
(
previousWritesTask
,
taskCompletionSource
)
=
await
GetWriteTaskAsync
().
ConfigureAwait
(
false
);
var
(
previousWritesTask
,
taskCompletionSource
)
=
await
GetWriteTaskAsync
(
keyToWriteActions
,
keyToWriteTask
,
key
,
writesToProcess
,
cancellationToken
).
ConfigureAwait
(
false
);
try
{
// Wait for all previous writes to be flushed.
...
...
@@ -116,55 +117,57 @@ internal partial class SQLitePersistentStorage
// to proceed.
taskCompletionSource
?.
TrySetResult
(
0
);
}
}
return
;
// Local functions
//[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/36114", OftenCompletesSynchronously = true)]
async
ValueTask
<(
Task
previousTask
,
TaskCompletionSource
<
int
>
taskCompletionSource
)>
GetWriteTaskAsync
()
[
PerformanceSensitive
(
"https://github.com/dotnet/roslyn/issues/36114"
,
OftenCompletesSynchronously
=
true
)]
private
async
ValueTask
<(
Task
previousTask
,
TaskCompletionSource
<
int
>
taskCompletionSource
)>
GetWriteTaskAsync
<
TKey
>(
MultiDictionary
<
TKey
,
Action
<
SqlConnection
>>
keyToWriteActions
,
Dictionary
<
TKey
,
Task
>
keyToWriteTask
,
TKey
key
,
ArrayBuilder
<
Action
<
SqlConnection
>>
writesToProcess
,
CancellationToken
cancellationToken
)
{
// Have to acquire the semaphore. We're going to mutate the shared 'keyToWriteActions'
// and 'keyToWriteTask' collections.
//
// Note: by blocking on _writeQueueGate we are guaranteed to see all the writes
// performed by FlushAllPendingWritesAsync.
using
(
await
_writeQueueGate
.
DisposableWaitAsync
(
cancellationToken
).
ConfigureAwait
(
false
))
{
//
Have to acquire the semaphore. We're going to mutate the shared 'keyToWriteActions'
//
and 'keyToWriteTask' collections.
//
// Note: by blocking on _writeQueueGate we are guaranteed to see all the writes
// performed by FlushAllPendingWritesAsync.
using
(
await
_writeQueueGate
.
DisposableWaitAsync
(
cancellationToken
).
ConfigureAwait
(
false
)
)
//
Get the writes we need to process.
//
Note: explicitly foreach so we operate on the struct enumerator for
//
MultiDictionary.ValueSet.
var
actions
=
keyToWriteActions
[
key
];
writesToProcess
.
EnsureCapacity
(
writesToProcess
.
Count
+
actions
.
Count
);
foreach
(
var
action
in
actions
)
{
// Get the writes we need to process.
// Note: explicitly foreach so we operate on the struct enumerator for
// MultiDictionary.ValueSet.
var
actions
=
keyToWriteActions
[
key
];
writesToProcess
.
EnsureCapacity
(
writesToProcess
.
Count
+
actions
.
Count
);
foreach
(
var
action
in
actions
)
{
writesToProcess
.
Add
(
action
);
}
writesToProcess
.
Add
(
action
);
}
// and clear them from the queues so we don't process things multiple times.
keyToWriteActions
.
Remove
(
key
);
// and clear them from the queues so we don't process things multiple times.
keyToWriteActions
.
Remove
(
key
);
// Find the existing task responsible for writing to this queue.
var
existingWriteTask
=
keyToWriteTask
.
TryGetValue
(
key
,
out
var
task
)
?
task
:
Task
.
CompletedTask
;
// Find the existing task responsible for writing to this queue.
var
existingWriteTask
=
keyToWriteTask
.
TryGetValue
(
key
,
out
var
task
)
?
task
:
Task
.
CompletedTask
;
if
(
writesToProcess
.
Count
==
0
)
{
// We have no writes of our own. But there may be an existing task that
// is writing out this queue. Return this so our caller can wait for
// all existing writes to complete.
return
(
previousTask
:
existingWriteTask
,
taskCompletionSource
:
null
);
}
if
(
writesToProcess
.
Count
==
0
)
{
// We have no writes of our own. But there may be an existing task that
// is writing out this queue. Return this so our caller can wait for
// all existing writes to complete.
return
(
previousTask
:
existingWriteTask
,
taskCompletionSource
:
null
);
}
// Create a TCS that represents our own work writing out "writesToProcess".
// Store it in keyToWriteTask so that if other threads come along, they'll
// wait for us to complete before doing their own reads/writes on this queue.
var
localCompletionSource
=
new
TaskCompletionSource
<
int
>();
// Create a TCS that represents our own work writing out "writesToProcess".
// Store it in keyToWriteTask so that if other threads come along, they'll
// wait for us to complete before doing their own reads/writes on this queue.
var
localCompletionSource
=
new
TaskCompletionSource
<
int
>();
keyToWriteTask
[
key
]
=
localCompletionSource
.
Task
;
keyToWriteTask
[
key
]
=
localCompletionSource
.
Task
;
return
(
previousTask
:
existingWriteTask
,
taskCompletionSource
:
localCompletionSource
);
}
return
(
previousTask
:
existingWriteTask
,
taskCompletionSource
:
localCompletionSource
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录