Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
79f9c9bc
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,发现更多精彩内容 >>
提交
79f9c9bc
编写于
2月 13, 2020
作者:
S
Sam Harwell
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Simplify the implementation of SizeToFitAsync
上级
d1a515d4
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
45 addition
and
58 deletion
+45
-58
src/EditorFeatures/Core.Wpf/IWpfDifferenceViewerExtensions.cs
...EditorFeatures/Core.Wpf/IWpfDifferenceViewerExtensions.cs
+44
-57
src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs
src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs
+1
-1
未找到文件。
src/EditorFeatures/Core.Wpf/IWpfDifferenceViewerExtensions.cs
浏览文件 @
79f9c9bc
...
...
@@ -9,6 +9,8 @@
using
Microsoft.VisualStudio.Text
;
using
Microsoft.VisualStudio.Text.Differencing
;
using
Microsoft.VisualStudio.Text.Editor
;
using
Microsoft.VisualStudio.Text.Projection
;
using
Microsoft.VisualStudio.Threading
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Editor.Shared.Extensions
...
...
@@ -17,50 +19,26 @@ internal static class IWpfDifferenceViewerExtensions
{
private
class
SizeToFitHelper
:
ForegroundThreadAffinitizedObject
{
private
int
_calculationStarted
;
private
readonly
IWpfDifferenceViewer
_diffViewer
;
private
readonly
TaskCompletionSource
<
object
>
_taskCompletion
;
private
readonly
double
_minWidth
;
private
double
_width
;
private
double
_height
;
public
SizeToFitHelper
(
IThreadingContext
threadingContext
,
IWpfDifferenceViewer
diffViewer
,
double
minWidth
)
:
base
(
threadingContext
)
{
_calculationStarted
=
0
;
_diffViewer
=
diffViewer
;
_minWidth
=
minWidth
;
_taskCompletion
=
new
TaskCompletionSource
<
object
>();
}
public
async
Task
SizeToFitAsync
()
public
async
Task
SizeToFitAsync
(
CancellationToken
cancellationToken
)
{
// The following work must always happen on UI thread.
AssertIsForeground
();
// We won't know how many lines there will be in the inline diff or how
// wide the widest line in the inline diff will be until the inline diff
// snapshot has been computed. We register an event handler here that will
// allow us to calculate the required width and height once the inline diff
// snapshot has been computed.
_diffViewer
.
DifferenceBuffer
.
SnapshotDifferenceChanged
+=
SnapshotDifferenceChanged
;
// The inline diff snapshot may already have been computed before we registered the
// above event handler. In this case, we can go ahead and calculate the required width
// and height.
CalculateSize
();
// IDifferenceBuffer calculates the inline diff snapshot on the UI thread (on idle).
// Since we are already on the UI thread, we need to yield control so that the
// inline diff snapshot computation (and the event handler we registered above to
// calculate required width and height) get a chance to run and we need to wait until
// this computation is complete. Once computation is complete, the width and height
// need to be set from the UI thread. We use ConfigureAwait(true) to stay on the UI thread.
await
_taskCompletion
.
Task
.
ConfigureAwait
(
true
);
// The following work must always happen on UI thread.
AssertIsForeground
();
await
ThreadingContext
.
JoinableTaskFactory
.
SwitchToMainThreadAsync
(
cancellationToken
);
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task (containing method uses JTF)
await
CalculateSizeAsync
(
cancellationToken
);
#pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task
// We have the height and width required to display the inline diff snapshot now.
// Set the height and width of the IWpfDifferenceViewer accordingly.
...
...
@@ -68,34 +46,44 @@ public async Task SizeToFitAsync()
_diffViewer
.
VisualElement
.
Height
=
_height
;
}
private
void
SnapshotDifferenceChanged
(
object
sender
,
SnapshotDifferenceChangeEventArgs
args
)
private
async
Task
<
IProjectionSnapshot
>
GetInlineBufferSnapshotAsync
(
CancellationToken
cancellationToken
)
{
// The following work must always happen on UI thread.
AssertIsForeground
();
cancellationToken
.
ThrowIfCancellationRequested
();
// This event handler will only be called when the inline diff snapshot computation is complete.
Contract
.
ThrowIfNull
(
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
);
// We can go ahead and calculate the required height and width now.
CalculateSize
();
if
(
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
is
{
}
snapshot
)
{
return
snapshot
;
}
private
void
CalculateSize
()
var
completionSource
=
new
TaskCompletionSource
<
IProjectionSnapshot
>(
TaskCreationOptions
.
RunContinuationsAsynchronously
);
_diffViewer
.
DifferenceBuffer
.
SnapshotDifferenceChanged
+=
HandleSnapshotDifferenceChanged
;
// Handle cases where the snapshot was set between the previous check and the event registration
if
(
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
is
{
}
snapshot2
)
completionSource
.
SetResult
(
snapshot2
);
try
{
// The following work must always happen on UI thread.
AssertIsForeground
();
return
await
completionSource
.
Task
.
WithCancellation
(
cancellationToken
).
ConfigureAwaitRunInline
();
}
finally
{
_diffViewer
.
DifferenceBuffer
.
SnapshotDifferenceChanged
-=
HandleSnapshotDifferenceChanged
;
}
if
((
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
==
null
)
||
(
Interlocked
.
CompareExchange
(
ref
_calculationStarted
,
1
,
0
)
==
1
)
)
// Local function
void
HandleSnapshotDifferenceChanged
(
object
sender
,
SnapshotDifferenceChangeEventArgs
e
)
{
// Return if inline diff snapshot is not yet ready or
// if the size calculation is already in progress.
return
;
// This event handler will only be called when the inline diff snapshot computation is complete.
Contract
.
ThrowIfNull
(
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
);
completionSource
.
SetResult
(
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
);
}
}
// Unregister the event handler - we don't need it anymore since the inline diff
// snapshot is available at this point.
_diffViewer
.
DifferenceBuffer
.
SnapshotDifferenceChanged
-=
SnapshotDifferenceChanged
;
private
async
Task
CalculateSizeAsync
(
CancellationToken
cancellationToken
)
{
await
ThreadingContext
.
JoinableTaskFactory
.
SwitchToMainThreadAsync
(
cancellationToken
)
;
IWpfTextView
textView
;
ITextSnapshot
snapshot
;
...
...
@@ -112,7 +100,9 @@ private void CalculateSize()
else
{
textView
=
_diffViewer
.
InlineView
;
snapshot
=
_diffViewer
.
DifferenceBuffer
.
CurrentInlineBufferSnapshot
;
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task (containing method uses JTF)
snapshot
=
await
GetInlineBufferSnapshotAsync
(
cancellationToken
);
#pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task
}
// Perform a layout without actually rendering the content on the screen so that
...
...
@@ -130,9 +120,6 @@ private void CalculateSize()
_height
=
textView
.
LineHeight
*
(
textView
.
ZoomLevel
/
100
)
*
// Height of each line.
snapshot
.
LineCount
;
// Number of lines.
Contract
.
ThrowIfFalse
(
IsNormal
(
_height
));
// Calculation of required height and width is now complete.
_taskCompletion
.
SetResult
(
null
);
}
private
static
bool
IsNormal
(
double
value
)
...
...
@@ -141,10 +128,10 @@ private static bool IsNormal(double value)
}
}
public
static
Task
SizeToFitAsync
(
this
IWpfDifferenceViewer
diffViewer
,
IThreadingContext
threadingContext
,
double
minWidth
=
400.0
)
public
static
Task
SizeToFitAsync
(
this
IWpfDifferenceViewer
diffViewer
,
IThreadingContext
threadingContext
,
double
minWidth
=
400.0
,
CancellationToken
cancellationToken
=
default
)
{
var
helper
=
new
SizeToFitHelper
(
threadingContext
,
diffViewer
,
minWidth
);
return
helper
.
SizeToFitAsync
();
return
helper
.
SizeToFitAsync
(
cancellationToken
);
}
}
}
src/EditorFeatures/Core.Wpf/Preview/PreviewFactoryService.cs
浏览文件 @
79f9c9bc
...
...
@@ -716,7 +716,7 @@ private ITextBuffer CreateNewPlainTextBuffer(TextDocument document, Cancellation
AssertIsForeground
();
// We use ConfigureAwait(true) to stay on the UI thread.
await
diffViewer
.
SizeToFitAsync
(
ThreadingContext
).
ConfigureAwait
(
true
);
await
diffViewer
.
SizeToFitAsync
(
ThreadingContext
,
cancellationToken
:
cancellationToken
).
ConfigureAwait
(
true
);
leftWorkspace
?.
EnableDiagnostic
();
rightWorkspace
?.
EnableDiagnostic
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录