Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
8d7cb3d6
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,发现更多精彩内容 >>
提交
8d7cb3d6
编写于
3月 17, 2017
作者:
J
Jason Malinowski
提交者:
GitHub
3月 17, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #17895 from jasonmalinowski/simplify-async-lazy
Simplify AsyncLazy
上级
2ba0d8f2
721ac11a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
24 addition
and
47 deletion
+24
-47
src/Workspaces/Core/Portable/Utilities/AsyncLazy`1.cs
src/Workspaces/Core/Portable/Utilities/AsyncLazy`1.cs
+24
-47
未找到文件。
src/Workspaces/Core/Portable/Utilities/AsyncLazy`1.cs
浏览文件 @
8d7cb3d6
...
...
@@ -387,9 +387,7 @@ private void StartAsynchronousComputation(AsynchronousComputationToStart computa
task
=
GetCachedValueAndCacheThisValueIfNoneCached_NoLock
(
task
);
}
// It's safe to synchronously complete this task, since the Task object hasn't been returned
// to the caller of GetValueAsync yet
requestToCompleteSynchronously
.
CompleteFromTaskSynchronously
(
task
);
requestToCompleteSynchronously
.
CompleteFromTask
(
task
);
}
// We avoid creating a full closure just to pass the token along
...
...
@@ -453,9 +451,11 @@ private void CompleteWithTask(Task<T> task, CancellationToken cancellationToken)
task
=
GetCachedValueAndCacheThisValueIfNoneCached_NoLock
(
task
);
}
// Complete the requests outside the lock. It's not necessary to do this (none of this is touching any shared state)
// but there's no reason to hold the lock so we could reduce any theoretical lock contention.
foreach
(
var
requestToComplete
in
requestsToComplete
)
{
requestToComplete
.
CompleteFromTask
Asynchronously
(
task
);
requestToComplete
.
CompleteFromTask
(
task
);
}
}
...
...
@@ -512,7 +512,7 @@ private void OnAsynchronousRequestCancelled(object state)
}
}
request
.
Cancel
Asynchronously
();
request
.
Cancel
();
if
(
cancellationTokenSource
!=
null
)
{
...
...
@@ -520,7 +520,12 @@ private void OnAsynchronousRequestCancelled(object state)
}
}
private
sealed
class
Request
/// <remarks>
/// This inherits from <see cref="TaskCompletionSource{TResult}"/> to avoid allocating two objects when we can just use one.
/// The public surface area of <see cref="TaskCompletionSource{TResult}"/> should probably be avoided in favor of the public
/// methods on this class for correct behavior.
/// </remarks>
private
sealed
class
Request
:
TaskCompletionSource
<
T
>
{
/// <summary>
/// The <see cref="CancellationToken"/> associated with this request. This field will be initialized before
...
...
@@ -529,73 +534,45 @@ private sealed class Request
private
CancellationToken
_cancellationToken
;
private
CancellationTokenRegistration
_cancellationTokenRegistration
;
// WARNING: this is a mutable struct, and thus cannot be made readonly
private
TaskCompletionSource
<
T
>
_taskCompletionSource
;
public
Request
()
// We want to always run continuations asynchronously. Running them synchronously could result in deadlocks:
// if we're looping through a bunch of Requests and completing them one by one, and the continuation for the
// first Request was then blocking waiting for a later Request, we would hang. It also could cause performance
// issues. If the first request then consumes a lot of CPU time, we're not letting other Requests complete that
// could use another CPU core at the same time.
public
Request
()
:
base
(
TaskCreationOptions
.
RunContinuationsAsynchronously
)
{
_taskCompletionSource
=
new
TaskCompletionSource
<
T
>();
}
public
Task
<
T
>
Task
=>
_taskCompletionSource
.
Task
;
public
void
RegisterForCancellation
(
Action
<
object
>
callback
,
CancellationToken
cancellationToken
)
{
_cancellationToken
=
cancellationToken
;
_cancellationTokenRegistration
=
cancellationToken
.
Register
(
callback
,
this
);
}
public
void
CompleteFromTaskAsynchronously
(
Task
<
T
>
task
)
{
System
.
Threading
.
Tasks
.
Task
.
Factory
.
StartNew
(
CompleteFromTaskSynchronouslyStub
,
task
,
CancellationToken
.
None
,
TaskCreationOptions
.
None
,
TaskScheduler
.
Default
);
}
private
void
CompleteFromTaskSynchronouslyStub
(
object
task
)
{
CompleteFromTaskSynchronously
((
Task
<
T
>)
task
);
}
public
void
CompleteFromTaskSynchronously
(
Task
<
T
>
task
)
public
void
CompleteFromTask
(
Task
<
T
>
task
)
{
// AsyncTaskMethodBuilder doesn't give us Try* methods, and the Set methods may throw if the task
// is already completed. The belief is that the race is somewhere between rare to impossible, and
// so we'll do a quick check to see if the task is already completed or otherwise just give it a shot
// and catch it if it fails
if
(
this
.
Task
.
IsCompleted
)
{
return
;
}
// As an optimization, we'll cancel the request even we did get a value for it.
// That way things abort sooner.
if
(
task
.
IsCanceled
||
_cancellationToken
.
IsCancellationRequested
)
{
Cancel
Synchronously
();
Cancel
();
}
else
if
(
task
.
IsFaulted
)
{
_taskCompletionSource
.
TrySetException
(
task
.
Exception
);
this
.
TrySetException
(
task
.
Exception
);
}
else
{
_taskCompletionSource
.
TrySetResult
(
task
.
Result
);
this
.
TrySetResult
(
task
.
Result
);
}
_cancellationTokenRegistration
.
Dispose
();
}
public
void
CancelAsynchronously
()
{
// Since there could be synchronous continuations on the TaskCancellationSource, we queue this to the threadpool
// to avoid inline running of other operations.
System
.
Threading
.
Tasks
.
Task
.
Factory
.
StartNew
(
CancelSynchronously
,
CancellationToken
.
None
,
TaskCreationOptions
.
None
,
TaskScheduler
.
Default
);
}
private
void
CancelSynchronously
()
public
void
Cancel
()
{
_taskCompletionSource
.
TrySetCanceled
(
_cancellationToken
);
this
.
TrySetCanceled
(
_cancellationToken
);
}
}
}
}
\ No newline at end of file
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录