Skip to content

Commit 3b02914

Browse files
committed
Fix mlc markdown link errors, warnings
1 parent 0beeb5c commit 3b02914

File tree

6 files changed

+80
-80
lines changed

6 files changed

+80
-80
lines changed

.github/workflows/docs_validate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: 🔗 Markup Link Checker (mlc)
2020
uses: becheran/[email protected]
2121
with:
22-
args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/* -p docfx -i https://aka.ms/onboardsupport,https://aka.ms/spot,https://msrc.microsoft.com/*,https://www.microsoft.com/msrc*,https://microsoft.com/msrc*,https://microsoft.sharepoint.com/*
22+
args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/*,https://badges.gitter.im/*,https://github.com/*,https://app.gitter.im/* -p docfx -i https://aka.ms/onboardsupport,https://aka.ms/spot,https://msrc.microsoft.com/*,https://www.microsoft.com/msrc*,https://microsoft.com/msrc*,https://microsoft.sharepoint.com/*
2323
- name: ⚙ Install prerequisites
2424
run: |
2525
./init.ps1 -UpgradePrerequisites

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ For significant changes we strongly recommend opening an issue to start a design
1919

2020
* [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/2.2) with the version matching our [global.json](global.json) file. The version you install must be at least the version specified in the global.json file, and must be within the same hundreds version for the 3rd integer: x.y.Czz (x.y.C must match, and zz must be at least as high).
2121
The easiest way to get this is to run the `init` script at the root of the repo. Use the `-InstallLocality Machine` and approve admin elevation if you wish so the SDK is always discoverable from VS. See the `init` script usage doc for more details.
22-
* Optional: [Visual Studio 2019](https://www.visualstudio.com/)
22+
* Optional: [Visual Studio 2022](https://visualstudio.microsoft.com/)
2323

2424
The only prerequisite for building, testing, and deploying from this repository
2525
is the [.NET SDK](https://get.dot.net/).

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
## Microsoft.VisualStudio.Threading
77

8-
[![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.svg)](https://nuget.org/packages/Microsoft.VisualStudio.Threading)
8+
[![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.svg)](https://www.nuget.org/packages/Microsoft.VisualStudio.Threading)
99

1010
Async synchronization primitives, async collections, TPL and dataflow extensions. The JoinableTaskFactory allows synchronously blocking the UI thread for async work. This package is applicable to any .NET application (not just Visual Studio).
1111

@@ -15,7 +15,7 @@ Async synchronization primitives, async collections, TPL and dataflow extensions
1515

1616
## Microsoft.VisualStudio.Threading.Analyzers
1717

18-
[![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.Analyzers.svg)](https://nuget.org/packages/Microsoft.VisualStudio.Threading.Analyzers)
18+
[![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.Analyzers.svg)](https://www.nuget.org/packages/Microsoft.VisualStudio.Threading.Analyzers)
1919

2020
Static code analyzer to detect common mistakes or potential issues regarding threading and async coding.
2121

doc/analyzers/VSTHRD010.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ private async Task CallVSAsync()
5858
}
5959
```
6060

61-
Refer to [Asynchronous and multithreaded programming within VS using the JoinableTaskFactory](http://blogs.msdn.com/b/andrewarnottms/archive/2014/05/07/asynchronous-and-multithreaded-programming-within-vs-using-the-joinabletaskfactory/) for more info.
61+
Refer to [Asynchronous and multithreaded programming within VS using the JoinableTaskFactory](https://devblogs.microsoft.com/premier-developer/asynchronous-and-multithreaded-programming-within-vs-using-the-joinabletaskfactory/) for more info.

doc/threading_rules.md

Lines changed: 72 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,27 @@ extensions](cookbook_vs.md)).
1313

1414
## The Rules
1515

16-
The rules are listed below with minimal examples. For a more thorough explanation with more examples, check out [this slideshow](https://www.slideshare.net/aarnott/the-3-vs-threading-rules).
16+
The rules are listed below with minimal examples. For a more thorough explanation with more examples, check out [this slideshow](https://www.slideshare.net/slideshow/the-3-vs-threading-rules/78280010).
1717

1818
### Rule #1. If a method has certain thread apartment requirements (STA or MTA) it must either:
1919
1. Have an asynchronous signature, and asynchronously marshal to the appropriate
20-
thread if it isn't originally invoked on a compatible thread. The recommended
20+
thread if it isn't originally invoked on a compatible thread. The recommended
2121
means of switching to the main thread is:
2222

2323
```csharp
2424
await joinableTaskFactoryInstance.SwitchToMainThreadAsync();
2525
```
2626

2727
OR
28-
28+
2929
2. Have a synchronous signature, and throw an exception when called on the wrong thread.
3030
This can be done in Visual Studio with `ThreadHelper.ThrowIfNotOnUIThread()` or
3131
`ThreadHelper.ThrowIfOnUIThread()`.
3232

3333
In particular, no method is allowed to synchronously marshal work to
3434
another thread (blocking while that work is done) except by using the second rule (below).
3535
Synchronous blocks in general are to be avoided whenever possible.
36-
36+
3737
### Rule #2. When an implementation of an already-shipped public API must call asynchronous code and block for its completion, it must do so by following this simple pattern:
3838

3939
```csharp
@@ -42,7 +42,7 @@ joinableTaskFactoryInstance.Run(async delegate
4242
await SomeOperationAsync(...);
4343
});
4444
```
45-
45+
4646
### Rule #3. If ever awaiting work that was started earlier, that work must be *joined*.
4747

4848
For example, one service kicks off some asynchronous work that may later become synchronously blocking:
@@ -57,22 +57,22 @@ JoinableTask longRunningAsyncWork = joinableTaskFactoryInstance.RunAsync(
5757

5858
then later that async work becomes blocking:
5959

60-
```csharp
60+
```csharp
6161
longRunningAsyncWork.Join();
6262
```
6363

64-
or perhaps
64+
or perhaps
6565

66-
```csharp
66+
```csharp
6767
await longRunningAsyncWork;
6868
```
6969

7070
Note however that this extra step is not necessary when awaiting is
7171
done immediately after kicking off an asynchronous operation.
72-
73-
In particular, no method should call `Task.Wait()` or `Task.Result` on
72+
73+
In particular, no method should call `Task.Wait()` or `Task.Result` on
7474
an incomplete `Task`.
75-
75+
7676
### Additional "honorable mention" rules: (Not JTF related)
7777

7878
### Rule #4. Never define `async void` methods. Make the methods return `Task` instead.
@@ -81,11 +81,11 @@ an incomplete `Task`.
8181
- Exceptions can't be reported to telemetry by the caller.
8282
- It's impossible for your VS package to responsibly block in `Package.Close`
8383
till your `async` work is done when it was kicked off this way.
84-
- Be cautious: `async delegate` or `async () =>` become `async void`
85-
methods when passed to a method that accepts `Action` delegates. Only
86-
pass `async` delegates to methods that accept `Func<Task>` or
84+
- Be cautious: `async delegate` or `async () =>` become `async void`
85+
methods when passed to a method that accepts `Action` delegates. Only
86+
pass `async` delegates to methods that accept `Func<Task>` or
8787
`Func<Task<T>>` parameters.
88-
88+
8989
Frequently Asked Questions
9090
---------------
9191

@@ -139,65 +139,65 @@ blocking thread to execute the continuations.
139139

140140
There are several reasons for this:
141141

142-
1. The COM transition synchronously blocks the calling thread. If the
143-
main thread isn't immediately pumping messages, the MTA thread will
144-
block until it handles the message. If you're on a threadpool thread,
145-
this ties up a precious resource and if your code may execute on
146-
multiple threadpool threads at once, there is a very real possibility
142+
1. The COM transition synchronously blocks the calling thread. If the
143+
main thread isn't immediately pumping messages, the MTA thread will
144+
block until it handles the message. If you're on a threadpool thread,
145+
this ties up a precious resource and if your code may execute on
146+
multiple threadpool threads at once, there is a very real possibility
147147
of [threadpool starvation](threadpool_starvation.md).
148-
2. Deadlock: if the main thread is blocked waiting for the background
149-
thread, and the main thread happens to be on top of some call stack
150-
(like WPF measure-layout) that suppresses the message pump, the code
148+
2. Deadlock: if the main thread is blocked waiting for the background
149+
thread, and the main thread happens to be on top of some call stack
150+
(like WPF measure-layout) that suppresses the message pump, the code
151151
that normally works will randomly deadlock.
152-
3. When the main thread is pumping messages, it will execute your code,
153-
regardless as to whether it is relevant to what the main thread may
154-
already be doing. If the main thread is in the main message pump,
155-
that's fine. But if the main thread is in a pumping wait (in
156-
managed code this could be almost anywhere as this includes locks,
157-
I/O, sync blocks, etc.) it could be a very bad time. We call these
158-
bad times "reentrancy" and the problem comes when you have component
159-
X running on the main thread in a pumping wait, the component Y
160-
uses COM marshalling to re-enter the main thread, and then Y calls
161-
(directly or indirectly) into component X. Component X is typically
162-
written with the assumption that by being on the main thread, it's
163-
isolated and single-threaded, and it usually isn't prepared to handle
164-
reentrancy. As a result, data corruption and/or deadlocks can result.
165-
Such has been the source of many deadlocks and crashes in VS for the
152+
3. When the main thread is pumping messages, it will execute your code,
153+
regardless as to whether it is relevant to what the main thread may
154+
already be doing. If the main thread is in the main message pump,
155+
that's fine. But if the main thread is in a pumping wait (in
156+
managed code this could be almost anywhere as this includes locks,
157+
I/O, sync blocks, etc.) it could be a very bad time. We call these
158+
bad times "reentrancy" and the problem comes when you have component
159+
X running on the main thread in a pumping wait, the component Y
160+
uses COM marshalling to re-enter the main thread, and then Y calls
161+
(directly or indirectly) into component X. Component X is typically
162+
written with the assumption that by being on the main thread, it's
163+
isolated and single-threaded, and it usually isn't prepared to handle
164+
reentrancy. As a result, data corruption and/or deadlocks can result.
165+
Such has been the source of many deadlocks and crashes in VS for the
166166
last few releases.
167-
4. Any method from a VS service that returns a pointer is probably
168-
inherently broken when called from a background thread. For example,
169-
`ItemID`s returned from `IVsHierarchy` are very often raw pointers cast
170-
to integers. These pointers are guaranteed to be valid for as long
171-
as you're on the main thread (and no event was raised to invalidate
172-
it). But when you call a `IVsHierarchy` method to get an `ItemID` back
173-
from a background thread, you leave the STA thread immediately as
174-
the call returns, meaning the pointer is unsafe to use. If you then
175-
go and pass that pointer back into the project system, the pointer
176-
could have been invalidated in the interim, and you'll end up causing
177-
an access violation crash in VS. The only safe way to deal with
178-
`ItemID`s (or any other pointer type) is while manually marshaled to
179-
the UI thread so that you know they are still valid for as long as
167+
4. Any method from a VS service that returns a pointer is probably
168+
inherently broken when called from a background thread. For example,
169+
`ItemID`s returned from `IVsHierarchy` are very often raw pointers cast
170+
to integers. These pointers are guaranteed to be valid for as long
171+
as you're on the main thread (and no event was raised to invalidate
172+
it). But when you call a `IVsHierarchy` method to get an `ItemID` back
173+
from a background thread, you leave the STA thread immediately as
174+
the call returns, meaning the pointer is unsafe to use. If you then
175+
go and pass that pointer back into the project system, the pointer
176+
could have been invalidated in the interim, and you'll end up causing
177+
an access violation crash in VS. The only safe way to deal with
178+
`ItemID`s (or any other pointer type) is while manually marshaled to
179+
the UI thread so that you know they are still valid for as long as
180180
you hold and use them.
181-
5. If your method runs on a background thread and has a loop that
182-
accesses a VS service, that can incur a lot of thread transitions
183-
which can hurt performance. If you were explicit in your code about
184-
the transition, you'd very likely move it to just before you enter
181+
5. If your method runs on a background thread and has a loop that
182+
accesses a VS service, that can incur a lot of thread transitions
183+
which can hurt performance. If you were explicit in your code about
184+
the transition, you'd very likely move it to just before you enter
185185
the loop, which would make your code more efficient from the start.
186-
6. Some VS services don't have proxy stubs registered and thus will fail
187-
to the type cast or on method invocation when your code executes on
186+
6. Some VS services don't have proxy stubs registered and thus will fail
187+
to the type cast or on method invocation when your code executes on
188188
a background thread.
189-
7. Some VS services get rewritten from native to managed code, which
190-
subtly changes them from single-threaded to free-threaded services.
191-
Unless the managed code is written to be thread-safe (most is not)
192-
this means that your managed code calling into a managed code VS
193-
service on a background thread will not transition to the UI thread
194-
first, and you are cruising for thread-safety bugs (data corruption,
195-
crashes, hangs, etc). By switching to the main thread yourself first,
196-
you won't be the poor soul who has crashes in their feature and has
197-
to debug it for days until you finally figure out that you were causing
198-
data corruption and a crash later on. Yes, you can blame the free
199-
threaded managed code that should have protected itself, but that's
200-
not very satisfying after days of investigation. And the owner of
189+
7. Some VS services get rewritten from native to managed code, which
190+
subtly changes them from single-threaded to free-threaded services.
191+
Unless the managed code is written to be thread-safe (most is not)
192+
this means that your managed code calling into a managed code VS
193+
service on a background thread will not transition to the UI thread
194+
first, and you are cruising for thread-safety bugs (data corruption,
195+
crashes, hangs, etc). By switching to the main thread yourself first,
196+
you won't be the poor soul who has crashes in their feature and has
197+
to debug it for days until you finally figure out that you were causing
198+
data corruption and a crash later on. Yes, you can blame the free
199+
threaded managed code that should have protected itself, but that's
200+
not very satisfying after days of investigation. And the owner of
201201
that code may refuse to fix their code and you'll have to fix yours anyway.
202202

203203
##### How do these rules protect me from re-entering random code on the main thread?
@@ -243,7 +243,7 @@ the moment. The debugger and Windows teams are working to improve that
243243
situation. In the meantime, we have learned several techniques to figure
244244
out what is causing the hang, and we're working to enhance the framework
245245
to automatically detect, self-analyze and report hangs to you so you have
246-
almost nothing to do but fix the code bug.
246+
almost nothing to do but fix the code bug.
247247

248248
In the meantime, the most useful technique for analyzing async hangs is to
249249
attach WinDBG to the process and dump out incomplete async methods' states.
@@ -283,7 +283,7 @@ priority via the `JoinableTask` it may call your code within.
283283

284284
##### What message priority is used to switch to (or resume on) the main thread, and can this be changed?
285285

286-
`JoinableTaskFactory`s default behavior is to switch to the main thread using
286+
`JoinableTaskFactory`'s default behavior is to switch to the main thread using
287287
`SynchronizationContext.Post`, which typically posts a message to the main thread,
288288
which puts it below RPC and above user input in priority.
289289

@@ -303,8 +303,8 @@ your own constructor that chains in the base constructor, passing in the
303303
required parameters. You are then free to directly instantiate your derived
304304
type by passing in either a `JoinableTaskContext` or a `JoinableTaskCollection`.
305305

306-
For more information on this topic, see Andrew Arnott's blog post
307-
[Asynchronous and multithreaded programming within VS using the
306+
For more information on this topic, see Andrew Arnott's blog post
307+
[Asynchronous and multithreaded programming within VS using the
308308
`JoinableTaskFactory`][JTFBlog].
309309

310310
[AsyncHangDebugging]: https://github.com/Microsoft/VSProjectSystem/blob/master/doc/scenario/analyze_hangs.md

0 commit comments

Comments
 (0)