This commit is contained in:
Andrew Arnott 2018-09-22 15:20:24 -07:00
Родитель b9c18b3920 1aadef7dde
Коммит 0c866e8700
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: A9B9910CDCCDA441
57 изменённых файлов: 1318 добавлений и 478 удалений

Просмотреть файл

@ -1,81 +0,0 @@
version: '{build}'
branches:
only:
- master
- /^v\d+(?:\.\d+)?$/
- /[\b_]validate\b/
skip_tags: true
skip_commits:
files:
- doc/*
- .github/*
- '**/*.md'
- .vsts-ci.yml
nuget:
disable_publish_on_pr: true
image: Visual Studio 2017
configuration: Release
environment:
VisualStudioVersion: 15.0
TreatWarningsAsErrors: true
CodeAnalysisTreatWarningsAsErrors: true
init:
- git config --global core.autocrlf true
install:
appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/v4.6.1/nuget.exe
before_build:
nuget restore src
build_script:
- msbuild src\Microsoft.VisualStudio.Threading.sln /p:platform="Any CPU" /nologo /m /v:minimal /t:build,pack /bl:msbuild.binlog
- msbuild src\Microsoft.VisualStudio.Threading.sln /p:platform=x64 /nologo /m /v:minimal /bl:msbuild_x64.binlog
- msbuild src\Microsoft.VisualStudio.Threading.sln /p:platform=x86 /nologo /m /v:minimal /bl:msbuild_x86.binlog
test_script:
- >-
md "bin\%configuration%"
SET testdir=bin\Microsoft.VisualStudio.Threading.Tests\%configuration%\
"%xunit20%\xunit.console.x86.exe"
"bin\Microsoft.VisualStudio.Threading.Tests\%configuration%\net451\Microsoft.VisualStudio.Threading.Tests.dll"
-noshadow
-html "bin\%configuration%\testresults_net451.html" -xml "bin\%configuration%\testresults_net451.xml"
-appveyor
-notrait "TestCategory=FailsInCloudTest"
-nologo
"%xunit20%\xunit.console.x86.exe"
"bin\Microsoft.VisualStudio.Threading.Tests\%configuration%\net452\Microsoft.VisualStudio.Threading.Tests.dll"
"bin\Microsoft.VisualStudio.Threading.Analyzers.Tests\%configuration%\net46\Microsoft.VisualStudio.Threading.Analyzers.Tests.dll"
-noshadow
-html "bin\%configuration%\testresults_net452.html" -xml "bin\%configuration%\testresults_net452.xml"
-appveyor
-notrait "TestCategory=FailsInCloudTest"
-nologo
"%xunit20%\xunit.console.x86.exe"
"bin\Microsoft.VisualStudio.Threading.Tests\%configuration%\net46\Microsoft.VisualStudio.Threading.Tests.dll"
-noshadow
-html "bin\%configuration%\testresults_net46.html" -xml "bin\%configuration%\testresults_net46.xml"
-appveyor
-notrait "TestCategory=FailsInCloudTest"
-nologo
dotnet test src\Microsoft.VisualStudio.Threading.Tests\Microsoft.VisualStudio.Threading.Tests.csproj
--no-build
-f netcoreapp1.0
--filter "TestCategory!=FailsInCloudTest"
dotnet test src\Microsoft.VisualStudio.Threading.Tests\Microsoft.VisualStudio.Threading.Tests.csproj
--no-build
-f netcoreapp2.0
artifacts:
- path: bin\**\*.nupkg
name: NuGet Package
- path: bin\AsyncDebugTools\x64\$(Configuration)\AsyncDebugTools.dll
name: WinDbg extension (x64)
- path: bin\AsyncDebugTools\x86\$(Configuration)\AsyncDebugTools.dll
name: WinDbg extension (x86)
- path: msbuild*.binlog
name: Build logs
- path: bin\**\testresults*
name: Test results

Просмотреть файл

@ -1,171 +1,43 @@
trigger:
branches:
include: ["master", "v15.7", "v15.8"]
include: ["master", "v15.8"]
paths:
exclude: [".github", "doc", "*.md"]
exclude: [".github", "doc", "*.md", ".appveyor.yml", ".travis.yml"]
steps:
- task: PowerShell@2
displayName: Set VSTS variables
inputs:
targetType: inline
script: |
if ($env:SignType -eq 'Real') {
$feedGuid = '09d8d03c-1ac8-456e-9274-4d2364527d99'
} else {
$feedGuid = 'da484c78-f942-44ef-b197-99e2a1bef53c'
}
variables:
TreatWarningsAsErrors: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
BuildPlatform: Any CPU
Write-Host "##vso[task.setvariable variable=feedGuid]$feedGuid"
resources:
containers:
- container: xenial
image: andrewarnott/linux-buildagent
if ($env:ComputerName.StartsWith('factoryvm', [StringComparison]::OrdinalIgnoreCase)) {
Write-Host "Running on hosted queue"
Write-Host "##vso[task.setvariable variable=Hosted]true"
}
jobs:
- job: Windows
pool: Hosted VS2017
steps:
- template: azure-pipelines/build.yml
- task: CmdLine@2
inputs:
script: |
del /s /q "%userprofile%\.nuget\packages"
del /s /q "%LocalAppData%\NuGet\Cache"
del /s /q "%AppData%\tsd-cache"
displayName: Purge package caches
condition: and(succeeded(), ne(variables['Hosted'], 'true'))
- job: Linux
pool:
vmImage: Ubuntu 16.04
container: xenial
variables:
GitLinkEnabled: false
steps:
- template: azure-pipelines/testfx.yml
parameters:
projectdirectory: src/Microsoft.VisualStudio.Threading.Tests
- task: NuGetToolInstaller@0
displayName: Pin nuget.exe version
inputs:
versionSpec: 4.6.1
- task: MicroBuildIBCMergePlugin@0
displayName: MicroBuild IBCMerge Plugin
inputs:
branch: master
condition: and(succeeded(), ne(variables['Hosted'], 'true'))
- task: MicroBuildSigningPlugin@1
displayName: MicroBuild Signing Plugin
inputs:
signType: $(SignType)
esrpSigning: true
zipSources: false
- task: NuGetCommand@2
inputs:
restoreSolution: '**\*.sln'
feedsToUse: config
displayName: Nuget restore packages
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build,pack /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild.binlog"
platform: Any CPU
configuration: $(BuildConfiguration)
displayName: Build Visual Studio solution
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild_x86.binlog"
platform: x86
configuration: $(BuildConfiguration)
displayName: Build AsyncDebugTools x86
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild_x64.binlog"
platform: x64
configuration: $(BuildConfiguration)
displayName: Build AsyncDebugTools x64
- task: MicroBuildCleanup@1
displayName: MicroBuild Cleanup
condition: succeededOrFailed()
## The rest of these steps are for deployment and skipped for PR builds
#- task: PublishBuildArtifacts@1
# inputs:
# PathtoPublish: $(build.sourcesdirectory)/bin
# ArtifactName: bin
# ArtifactType: Container
# condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishBuildArtifacts@1
displayName: Publish build_logs
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/build_logs
ArtifactName: build_logs
ArtifactType: Container
condition: succeededOrFailed()
- task: CopyFiles@1
displayName: Collecting symbols artifacts
inputs:
SourceFolder: bin
Contents: |
Microsoft.VisualStudio.Threading/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.dll
Microsoft.VisualStudio.Threading/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.pdb
Microsoft.VisualStudio.Threading.Analyzers/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.Analyzers.dll
Microsoft.VisualStudio.Threading.Analyzers/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.Analyzers.pdb
AsyncDebugTools/x86/$(BuildConfiguration)/AsyncDebugTools.dll
AsyncDebugTools/x86/$(BuildConfiguration)/AsyncDebugTools.pdb
AsyncDebugTools/x64/$(BuildConfiguration)/AsyncDebugTools.dll
AsyncDebugTools/x64/$(BuildConfiguration)/AsyncDebugTools.pdb
TargetFolder: $(Build.ArtifactStagingDirectory)/symbols
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishBuildArtifacts@1
displayName: Publish symbols
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/symbols
ArtifactName: symbols
ArtifactType: Container
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: CopyFiles@1
displayName: Collecting deployable packages
inputs:
Contents: |
bin/**/$(BuildConfiguration)/**/*.nupkg
TargetFolder: $(Build.ArtifactStagingDirectory)/deployables
flattenFolders: true
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: CopyFiles@1
displayName: Collecting deployable binaries
inputs:
Contents: |
x86/$(BuildConfiguration)/AsyncDebugTools.dll
x64/$(BuildConfiguration)/AsyncDebugTools.dll
SourceFolder: bin/AsyncDebugTools
TargetFolder: $(Build.ArtifactStagingDirectory)/deployables
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishBuildArtifacts@1
displayName: Publish deployables
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/deployables
ArtifactName: deployables
ArtifactType: Container
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishSymbols@2
displayName: Archive symbols
inputs:
SymbolsFolder: $(Build.ArtifactStagingDirectory)/symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: NuGetCommand@2
displayName: Push NuGet packages
inputs:
command: push
searchPatternPush: '$(Build.SourcesDirectory)\bin\**\$(BuildConfiguration)\**\*.nupkg;!**\*.symbols.nupkg;!**/VS.*.nupkg'
publishVstsFeed: $(feedGuid)
allowPackageConflicts: true
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- job: macOS
pool:
vmImage: macOS 10.13
variables:
GitLinkEnabled: false
steps:
- template: azure-pipelines/testfx.yml
parameters:
projectdirectory: src/Microsoft.VisualStudio.Threading.Tests

Просмотреть файл

@ -2,7 +2,7 @@ Microsoft.VisualStudio.Threading
=================================
[![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.svg)](https://nuget.org/packages/Microsoft.VisualStudio.Threading)
[![Build status](https://ci.appveyor.com/api/projects/status/kv58v4d03td5ngna/branch/master?svg=true)](https://ci.appveyor.com/project/AArnott/vs-threading/branch/master)
[![Build Status](https://andrewarnott.visualstudio.com/OSS/_apis/build/status/vs-threading)](https://andrewarnott.visualstudio.com/OSS/_build/latest?definitionId=16)
[![Join the chat at https://gitter.im/vs-threading/Lobby](https://badges.gitter.im/vs-threading/Lobby.svg)](https://gitter.im/vs-threading/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Analyzers: [![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStudio.Threading.Analyzers.svg)](https://nuget.org/packages/Microsoft.VisualStudio.Threading.Analyzers)
@ -27,14 +27,14 @@ Analyzers: [![NuGet package](https://img.shields.io/nuget/v/Microsoft.VisualStud
* Await on a `TaskScheduler` to switch to it.
Switch to a background thread with `await TaskScheduler.Default;`
* Await on a `Task` with a timeout
* Await on a `Task` with cancellation
* Await on a `Task` with cancellation
* `JoinableTaskFactory` that allows you to schedule asynchronous or synchronous work
that does not deadlock with the UI thread even when the UI thread needs to
synchronously block on the result.
## Documentation
* [Overview documentation](doc/index.md)
* [Overview documentation](doc/index.md)
* [Diagnostic analyzer rules](doc/analyzers/index.md)
## Supported platforms

Просмотреть файл

@ -0,0 +1,46 @@
steps:
- task: MicroBuildCleanup@1
condition: and(succeededOrFailed(), ne(variables['Hosted'], 'true'))
displayName: MicroBuild Cleanup
- task: NuGetCommand@2
inputs:
command: push
searchPatternPush: '$(Build.SourcesDirectory)\bin\**\$(BuildConfiguration)\**\*.nupkg;!**\*.symbols.nupkg;!**/VS.*.nupkg'
publishVstsFeed: $(feedGuid)
allowPackageConflicts: true
displayName: Push packages to VSTS feed
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: CopyFiles@1
inputs:
SourceFolder: bin
Contents: |
Microsoft.VisualStudio.Threading/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.dll
Microsoft.VisualStudio.Threading/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.pdb
Microsoft.VisualStudio.Threading.Analyzers/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.Analyzers.dll
Microsoft.VisualStudio.Threading.Analyzers/$(BuildConfiguration)/**/Microsoft.VisualStudio.Threading.Analyzers.pdb
AsyncDebugTools/x86/$(BuildConfiguration)/AsyncDebugTools.dll
AsyncDebugTools/x86/$(BuildConfiguration)/AsyncDebugTools.pdb
AsyncDebugTools/x64/$(BuildConfiguration)/AsyncDebugTools.dll
AsyncDebugTools/x64/$(BuildConfiguration)/AsyncDebugTools.pdb
TargetFolder: $(Build.ArtifactStagingDirectory)/symbols
displayName: Collecting symbols artifacts
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/symbols
ArtifactName: symbols
ArtifactType: Container
displayName: Publish symbols as Azure DevOps artifacts
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishSymbols@2
inputs:
SymbolsFolder: $(Build.ArtifactStagingDirectory)/symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: Publish symbols to symbol server
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))

Просмотреть файл

@ -0,0 +1,23 @@
steps:
- task: CmdLine@2
inputs:
script: |
del /s /q "%userprofile%\.nuget\packages"
del /s /q "%LocalAppData%\NuGet\Cache"
del /s /q "%AppData%\tsd-cache"
displayName: Purge package caches
condition: and(succeeded(), ne(variables['Hosted'], 'true'))
- task: MicroBuildIBCMergePlugin@0
inputs:
branch: rel/d15.8
displayName: Install MicroBuild IBCMerge Plugin
condition: and(succeeded(), ne(variables['Hosted'], 'true'))
- task: MicroBuildSigningPlugin@1
inputs:
signType: $(SignType)
zipSources: false
displayName: Install MicroBuild Signing Plugin
condition: and(succeeded(), ne(variables['Hosted'], 'true'))

150
azure-pipelines/build.yml Normal file
Просмотреть файл

@ -0,0 +1,150 @@
steps:
- script: |
dotnet tool install --tool-path . nbgv
.\nbgv cloud -p src
displayName: Set build number
condition: ne(variables['system.pullrequest.isfork'], true)
- task: PowerShell@2
displayName: Set VSTS variables
inputs:
targetType: inline
script: |
if ($env:SignType -eq 'Real') {
$feedGuid = '09d8d03c-1ac8-456e-9274-4d2364527d99'
} else {
$feedGuid = 'da484c78-f942-44ef-b197-99e2a1bef53c'
}
Write-Host "##vso[task.setvariable variable=feedGuid]$feedGuid"
if ($env:ComputerName.StartsWith('factoryvm', [StringComparison]::OrdinalIgnoreCase)) {
Write-Host "Running on hosted queue"
Write-Host "##vso[task.setvariable variable=Hosted]true"
}
if ($env:SYSTEM_COLLECTIONID -eq '011b8bdf-6d56-4f87-be0d-0092136884d9') {
Write-Host "Running on official devdiv account: $env:System_TeamFoundationCollectionUri"
} else {
Write-Host "Running under OSS account: $env:System_TeamFoundationCollectionUri"
}
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
- template: azure-pipeline.microbuild.before.yml
- task: DotNetCoreInstaller@0
displayName: Install .NET Core SDK 2.1.300
inputs:
packageType: sdk
version: 2.1.300
condition: and(succeeded(), ne(variables['Hosted'], 'true')) # Hosted agents already have this.
- script: dotnet --info
displayName: Show dotnet SDK info
# We have to use the traditional nuget.exe for restoring since we have vcxproj projects too.
- task: NuGetToolInstaller@0
displayName: Pin nuget.exe version
inputs:
versionSpec: 4.6.1
- powershell: nuget restore src\Microsoft.VisualStudio.Threading.sln
displayName: Nuget restore packages
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build,pack /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild.binlog"
platform: Any CPU
configuration: $(BuildConfiguration)
displayName: Build Visual Studio solution
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild_x86.binlog"
platform: x86
configuration: $(BuildConfiguration)
displayName: Build AsyncDebugTools x86
- task: VSBuild@1
inputs:
vsVersion: 15.0
msbuildArgs: /t:build /m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild_x64.binlog"
platform: x64
configuration: $(BuildConfiguration)
displayName: Build AsyncDebugTools x64
- task: DotNetCoreCLI@2
displayName: Run tests
inputs:
command: test
projects: src/**/*.Tests.csproj
arguments: --configuration $(BuildConfiguration) --no-build --filter "TestCategory!=FailsInCloudTest" -v n
condition: and(succeeded(), ne(variables['SignType'], 'real'))
- task: CopyFiles@1
inputs:
Contents: |
obj/**/project.assets.json
TargetFolder: $(Build.ArtifactStagingDirectory)/projectAssetsJson
displayName: Collecting project.assets.json artifacts
condition: succeededOrFailed()
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/projectAssetsJson
ArtifactName: projectAssetsJson
ArtifactType: Container
displayName: Publish projectAssetsJson artifacts
condition: and(succeededOrFailed(), ne(variables['system.pullrequest.isfork'], true))
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/build_logs
ArtifactName: build_logs
ArtifactType: Container
displayName: Publish build_logs artifacts
condition: and(succeededOrFailed(), ne(variables['system.pullrequest.isfork'], true))
## The rest of these steps are for deployment and skipped for PR builds
#- task: PublishBuildArtifacts@1
# inputs:
# PathtoPublish: $(build.sourcesdirectory)/bin
# ArtifactName: bin
# ArtifactType: Container
# condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'), ne(variables['system.pullrequest.isfork'], true))
- task: VSTest@2
displayName: Run tests on .NET Framework (with code coverage)
inputs:
testFiltercriteria: TestCategory!=FailsInCloudTest
searchFolder: $(System.DefaultWorkingDirectory)\bin
testAssemblyVer2: |
**\*tests*.dll
platform: $(BuildPlatform)
configuration: $(BuildConfiguration)
codeCoverageEnabled: true
condition: and(succeeded(), ne(variables['SignType'], 'real'))
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
- template: azure-pipeline.microbuild.after.yml
- task: CopyFiles@1
inputs:
Contents: |
bin/**/$(BuildConfiguration)/**/*.nupkg
bin/AsyncDebugTools/x86/$(BuildConfiguration)/AsyncDebugTools.dll
bin/AsyncDebugTools/x64/$(BuildConfiguration)/AsyncDebugTools.dll
TargetFolder: $(Build.ArtifactStagingDirectory)/deployables
flattenFolders: true
displayName: Collecting deployables
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/deployables
ArtifactName: deployables
ArtifactType: Container
displayName: Publish deployables artifacts
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'), ne(variables['system.pullrequest.isfork'], true))

Просмотреть файл

@ -0,0 +1,17 @@
trigger:
branches:
include: ["master", "v15.8"]
paths:
exclude: [".github", "doc", "*.md", ".appveyor.yml", ".travis.yml"]
variables:
TreatWarningsAsErrors: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
BuildPlatform: Any CPU
jobs:
- job: Windows
pool: VSEng-MicroBuildVS2017
steps:
- template: build.yml

Просмотреть файл

@ -0,0 +1,30 @@
steps:
- script: dotnet restore
displayName: Restore packages
workingDirectory: ${{ parameters.projectdirectory }}
- script: dotnet build -v n -f netcoreapp1.0 -c $(BuildConfiguration) --no-restore /bl:"$(Build.ArtifactStagingDirectory)/build_logs/netcoreapp1.0.binlog" -p:GitLinkEnabled=false
displayName: Build test for netcoreapp1.0
workingDirectory: ${{ parameters.projectdirectory }}
- script: dotnet build -v n -f netcoreapp2.0 -c $(BuildConfiguration) --no-restore /bl:"$(Build.ArtifactStagingDirectory)/build_logs/netcoreapp2.0.binlog" -p:GitLinkEnabled=false
displayName: Build test for netcoreapp2.0
workingDirectory: ${{ parameters.projectdirectory }}
- script: dotnet test -v n -f netcoreapp1.0 -c $(BuildConfiguration) --no-build --filter "TestCategory!=FailsInCloudTest"
displayName: Run tests for netcoreapp1.0 on the .NET Core 1.0.11 runtime
workingDirectory: ${{ parameters.projectdirectory }}
env:
DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX: 0
RuntimeFrameworkVersion: 1.0.11
- script: dotnet test -v n -f netcoreapp1.0 -c $(BuildConfiguration) --no-build --filter "TestCategory!=FailsInCloudTest"
displayName: Run tests for netcoreapp1.0 on the .NET Core 1.1.8 runtime
workingDirectory: ${{ parameters.projectdirectory }}
env:
DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX: 0
RuntimeFrameworkVersion: 1.1.8
- script: dotnet test -v n -f netcoreapp2.0 -c $(BuildConfiguration) --no-build --filter "TestCategory!=FailsInCloudTest"
displayName: Run tests for netcoreapp2.0 on the .NET Core 2.0.7 runtime
workingDirectory: ${{ parameters.projectdirectory }}
env:
DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX: 0
RuntimeFrameworkVersion: 2.0.7
enabled: false # TODO: figure out why this step hangs

Просмотреть файл

@ -0,0 +1,38 @@
# VSTHRD111 Use `.ConfigureAwait(bool)`
Some code bases, particularly libraries with no affinity to an app's UI thread, are advised to use `.ConfigureAwait(false)` for each and every _await_ because it can avoid deadlocks after those calls start on an application's UI thread and the app later decides to synchronously block the UI thread waiting for those tasks to finish. Using `.ConfigureAwait(false)` also allows continuations to switch to a background thread even when no synchronous blocking would cause a deadlock, which makes for a more responsive application and possibly higher throughput of async operations.
Note that this scenario can also be solved using the `JoinableTaskFactory`, but many class libraries may not wish to depend on the application proffers an instance of that type to the library. Where JoinableTaskFactory _does_ apply, use of `.ConfigureAwait(false)` is _not_ recommended. See [this topic](https://github.com/Microsoft/vs-threading/blob/master/doc/cookbook_vs.md#should-i-await-a-task-with-configureawaitfalse) for more on when `.ConfigureAwait(false)` and `.ConfigureAwait(true)` are appropriate.
**This analyzer's diagnostics are *hidden* by default**. You should enable the rule for libraries that use to require this await suffix.
## Examples of patterns that are flagged by this analyzer
Any await on `Task` or `ValueTask` without the `.ConfigureAwait(bool)` method called on it will be flagged.
```csharp
async Task FooAsync() {
await DoStuffAsync(); // This line is flagged
await DoMoreStuffAsync(); // This line is flagged
}
async Task DoStuffAsync() { /* ... */ }
async ValueTask DoMoreStuffAsync() { /* ... */ }
```
## Solution
Add `.ConfigureAwait(false)` or `.ConfigureAwait(true)` to the awaited `Task` or `ValueTask`.
```csharp
async Task FooAsync() {
await DoStuffAsync().ConfigureAwait(true);
await DoMoreStuffAsync().ConfigureAwait(false);
}
async Task DoStuffAsync() { /* ... */ }
async ValueTask DoMoreStuffAsync() { /* ... */ }
```
Code fixes are offered for for this diagnostic to add either `.ConfigureAwait(false)` or `.ConfigureAwait(true)`
to an awaited expression.

Просмотреть файл

@ -3,8 +3,14 @@
The .NET Guidelines for async methods includes that such methods
should have names that include an "Async" suffix.
Methods that return awaitable types such as `Task` or `ValueTask`
should have an Async suffix.
Methods that do not return awaitable types should not use the Async suffix.
## Examples of patterns that are flagged by this analyzer
This `Task`-returning method should have a name that ends with Async:
```csharp
async Task DoSomething() // analyzer flags this line
{
@ -12,15 +18,30 @@ async Task DoSomething() // analyzer flags this line
}
```
This method should not have a name that ends with Async, since it does not return an awaitable type:
```csharp
bool DoSomethingElseAsync() // analyzer flags this line
{
return false;
}
```
## Solution
Simply rename the method to end in "Async":
Simply rename the method to end in "Async" (or remove the suffix, as appropriate):
```csharp
async Task DoSomethingAsync()
{
await Task.Yield();
}
bool DoSomethingElse()
{
return false;
}
```
A code fix exists to automatically rename such methods.

Просмотреть файл

@ -23,6 +23,7 @@ ID | Title | Severity | Supports
[VSTHRD108](VSTHRD108.md) | Assert thread affinity unconditionally | Advisory | [1st rule](../threading_rules.md#Rule1), [VSTHRD010](VSTHRD010.md)
[VSTHRD109](VSTHRD109.md) | Switch instead of assert in async methods | Advisory | [1st rule](../threading_rules.md#Rule1)
[VSTHRD110](VSTHRD110.md) | Observe result of async calls | Advisory
[VSTHRD110](VSTHRD111.md) | Use `.ConfigureAwait(bool)` | Advisory
[VSTHRD200](VSTHRD200.md) | Use `Async` naming convention | Guideline | [VSTHRD103](VSTHRD103.md)
## Severity descriptions

Просмотреть файл

@ -7,6 +7,8 @@ namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@ -20,11 +22,19 @@ namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
public class Test : CSharpCodeFixTest<TAnalyzer, TCodeFix, XUnitVerifier>
{
private static readonly ImmutableArray<string> VSSDKPackageReferences = ImmutableArray.Create(new string[] {
Path.Combine("Microsoft.VisualStudio.Shell.Interop", "7.10.6071", "lib", "Microsoft.VisualStudio.Shell.Interop.dll"),
Path.Combine("Microsoft.VisualStudio.Shell.Interop.11.0", "11.0.61030", "lib", "Microsoft.VisualStudio.Shell.Interop.11.0.dll"),
Path.Combine("Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime", "14.3.25407", "lib", "Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll"),
Path.Combine("Microsoft.VisualStudio.Shell.Immutable.14.0", "14.3.25407", "lib\\net45", "Microsoft.VisualStudio.Shell.Immutable.14.0.dll"),
Path.Combine("Microsoft.VisualStudio.Shell.14.0", "14.3.25407", "lib", "Microsoft.VisualStudio.Shell.14.0.dll"),
"Microsoft.VisualStudio.Shell.Interop.dll",
"Microsoft.VisualStudio.Shell.Interop.11.0.dll",
"Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll",
"Microsoft.VisualStudio.Shell.Immutable.14.0.dll",
"Microsoft.VisualStudio.Shell.14.0.dll",
});
private static readonly ImmutableArray<string> AdditionalReferencesFromBinFolder = ImmutableArray.Create(new string[] {
"System.Threading.Tasks.Extensions.dll",
});
private static readonly ImmutableArray<string> AdditionalReferencesFromGAC = ImmutableArray.Create(new string[] {
"System.Threading.Tasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
});
public Test()
@ -32,7 +42,9 @@ namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
this.SolutionTransforms.Add((solution, projectId) =>
{
var parseOptions = (CSharpParseOptions)solution.GetProject(projectId).ParseOptions;
solution = solution.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion.CSharp7_1));
solution = solution.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion.CSharp7_1))
.AddMetadataReferences(projectId, AdditionalReferencesFromBinFolder.Select(f => MetadataReference.CreateFromFile(Path.Combine(Environment.CurrentDirectory, f))))
.AddMetadataReferences(projectId, AdditionalReferencesFromGAC.Select(assemblyName => MetadataReference.CreateFromFile(Assembly.Load(assemblyName).Location)));
if (this.HasEntryPoint)
{
@ -54,7 +66,7 @@ namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
{
solution = solution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(IOleServiceProvider).Assembly.Location));
var nugetPackagesFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
var nugetPackagesFolder = Environment.CurrentDirectory;
foreach (var reference in VSSDKPackageReferences)
{
solution = solution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(Path.Combine(nugetPackagesFolder, reference)));
@ -91,4 +103,4 @@ namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
}
}
}
}
}

Просмотреть файл

@ -21,10 +21,11 @@
<ItemGroup>
<PackageReference Include="MicroBuild.VisualStudio" Version="$(MicroBuildVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.3.2" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.1" />
<PackageReference Include="Microsoft.VisualStudio.OLE.Interop" Version="7.10.6070" />
<PackageReference Include="Microsoft.VisualStudio.Shell.14.0" Version="14.3.25407" IncludeAssets="none" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.11.0" Version="11.0.61030" IncludeAssets="none" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime" Version="14.3.25407" IncludeAssets="none" />
<PackageReference Include="Microsoft.VisualStudio.Shell.14.0" Version="14.3.25407" IncludeAssets="runtime" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.11.0" Version="11.0.61030" IncludeAssets="runtime" />
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime" Version="14.3.25407" IncludeAssets="runtime" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="1.0.0-beta1-63310-01" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.XUnit" Version="1.0.0-beta1-63310-01" />
<PackageReference Include="xunit" Version="2.2.0" />
@ -50,4 +51,4 @@
<CustomToolNamespace>AdditionalFiles</CustomToolNamespace>
</EmbeddedResource>
</ItemGroup>
</Project>
</Project>

Просмотреть файл

@ -28,7 +28,7 @@ class Test {
Task<int> FooAsync() {
Task t = Task.FromResult(1);
t.GetAwaiter().GetResult(); // VSTHRD002, VSTHRD103, VSTHRD102
jtf.Run(async delegate { await BarAsync(); }); // VSTHRD103, VSTHRD102
jtf.Run(async delegate { await BarAsync().ConfigureAwait(true); }); // VSTHRD103, VSTHRD102
return Task.FromResult(1);
}

Просмотреть файл

@ -61,10 +61,6 @@ class Test {
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -100,10 +96,6 @@ class Test {
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -189,10 +181,6 @@ class Test {
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -226,10 +214,6 @@ class Test {
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -261,7 +245,7 @@ using Microsoft.VisualStudio.Shell.Interop;
class Test {
Test() {
Test.VerifyOnUIThread();
VerifyOnUIThread();
Foo();
}
@ -303,10 +287,6 @@ class Test {
ExpectedDiagnostics = { expected },
FixedCode = fix1,
CodeFixIndex = CodeFixIndex.VerifyOnUIThread,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
await new Verify.Test
@ -315,10 +295,6 @@ class Test {
ExpectedDiagnostics = { expected },
FixedCode = fix2,
CodeFixIndex = CodeFixIndex.ThrowIfNotOnUIThreadIndex1,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -384,10 +360,6 @@ class Test {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorSync).WithSpan(8, 13, 8, 24).WithArguments("IVsSolution", "Test.VerifyOnUIThread") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.ThrowIfNotOnUIThreadIndex0,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -542,7 +514,7 @@ class Test {
}
void H() {
Test.VerifyOnUIThread();
VerifyOnUIThread();
F();
G();
}
@ -561,10 +533,6 @@ class Test {
},
FixedCode = fix,
CodeFixIndex = CodeFixIndex.VerifyOnUIThread,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -769,10 +737,6 @@ class Test {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorSync).WithSpan(11, 17, 11, 28).WithArguments("IVsSolution", "Test.VerifyOnUIThread") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.VerifyOnUIThread,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -824,10 +788,6 @@ class Test {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorSync).WithSpan(12, 17, 12, 28).WithArguments("IVsSolution", "Test.VerifyOnUIThread") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.VerifyOnUIThread,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -901,10 +861,6 @@ class Test {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorSync).WithSpan(11, 17, 11, 28).WithArguments("IVsSolution", "Test.VerifyOnUIThread") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.VerifyOnUIThread,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1298,10 +1254,6 @@ class Test : AsyncPackage {
},
FixedCode = fix,
CodeFixIndex = CodeFixIndex.NotThreadHelper,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1345,10 +1297,6 @@ class Test : AsyncPackage {
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1439,10 +1387,6 @@ class Test : AsyncPackage {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorAsync).WithSpan(13, 65, 13, 76).WithArguments("IVsShell", "JoinableTaskFactory.SwitchToMainThreadAsync") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.NotThreadHelper,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1484,7 +1428,7 @@ class Test : AsyncPackage {
static Task MySwitchingMethodAsync(bool foo = false, CancellationToken ct = default(CancellationToken)) => TplExtensions.CompletedTask;
protected override async Task InitializeAsync(System.Threading.CancellationToken cancellationToken, IProgress<ServiceProgressData> progress) {
await Test.MySwitchingMethodAsync(ct: cancellationToken);
await MySwitchingMethodAsync(ct: cancellationToken);
await base.InitializeAsync(cancellationToken, progress);
var shell = await asp.GetServiceAsync(typeof(SVsShell)) as IVsShell;
}
@ -1496,10 +1440,6 @@ class Test : AsyncPackage {
ExpectedDiagnostics = { Verify.Diagnostic(DescriptorAsync).WithSpan(17, 65, 17, 76).WithArguments("IVsShell", "JoinableTaskFactory.SwitchToMainThreadAsync") },
FixedCode = fix,
CodeFixIndex = CodeFixIndex.MySwitchingMethodAsync,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1681,10 +1621,6 @@ class A
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}
@ -1724,10 +1660,6 @@ class A
TestCode = test,
ExpectedDiagnostics = { expected },
FixedCode = fix,
// Expected: SimpleMemberAccessExpression
// Actual: QualifiedName
CodeFixValidationMode = CodeFixValidationMode.None,
}.RunAsync();
}

Просмотреть файл

@ -0,0 +1,172 @@
namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
{
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
using Verify = CSharpCodeFixVerifier<VSTHRD111UseConfigureAwaitAnalyzer, VSTHRD111UseConfigureAwaitCodeFix>;
public class VSTHRD111UseConfigureAwaitAnalyzerTests
{
[Fact]
public async Task AwaitOnTask_NoSuffix_GeneratesDiagnostic()
{
var test = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await [|BarAsync()|];
}
Task BarAsync() => default;
}
";
var fixFalse = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await BarAsync().ConfigureAwait(false);
}
Task BarAsync() => default;
}
";
var fixTrue = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await BarAsync().ConfigureAwait(true);
}
Task BarAsync() => default;
}
";
await new Verify.Test
{
TestCode = test,
FixedCode = fixFalse,
CodeFixEquivalenceKey = false.ToString(),
}.RunAsync();
await new Verify.Test
{
TestCode = test,
FixedCode = fixTrue,
CodeFixEquivalenceKey = true.ToString(),
}.RunAsync();
}
[Fact]
public async Task AwaitOnValueTask_NoSuffix_GeneratesDiagnostic()
{
var test = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await [|BarAsync()|];
}
ValueTask BarAsync() => default;
}
";
var fixFalse = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await BarAsync().ConfigureAwait(false);
}
ValueTask BarAsync() => default;
}
";
var fixTrue = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
await BarAsync().ConfigureAwait(true);
}
ValueTask BarAsync() => default;
}
";
await new Verify.Test
{
TestCode = test,
FixedCode = fixFalse,
CodeFixEquivalenceKey = false.ToString(),
}.RunAsync();
await new Verify.Test
{
TestCode = test,
FixedCode = fixTrue,
CodeFixEquivalenceKey = true.ToString(),
}.RunAsync();
}
[Fact]
public async Task AwaitOnTaskOfT_NoSuffix_GeneratesDiagnostic()
{
var test = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
int total = await [|BarAsync()|] + 3;
}
Task<int> BarAsync() => default;
}
";
var fixFalse = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
int total = await BarAsync().ConfigureAwait(false) + 3;
}
Task<int> BarAsync() => default;
}
";
var fixTrue = @"
using System.Threading.Tasks;
class Test {
async Task Foo()
{
int total = await BarAsync().ConfigureAwait(true) + 3;
}
Task<int> BarAsync() => default;
}
";
await new Verify.Test
{
TestCode = test,
FixedCode = fixFalse,
CodeFixEquivalenceKey = false.ToString(),
}.RunAsync();
await new Verify.Test
{
TestCode = test,
FixedCode = fixTrue,
CodeFixEquivalenceKey = true.ToString(),
}.RunAsync();
}
}
}

Просмотреть файл

@ -1,12 +1,17 @@
namespace Microsoft.VisualStudio.Threading.Analyzers.Tests
{
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
using Verify = CSharpCodeFixVerifier<VSTHRD200UseAsyncNamingConventionAnalyzer, VSTHRD200UseAsyncNamingConventionCodeFix>;
public class VSTHRD200UseAsyncNamingConventionAnalyzerTests
{
private static readonly DiagnosticDescriptor AddSuffixDescriptor = VSTHRD200UseAsyncNamingConventionAnalyzer.AddAsyncDescriptor;
private static readonly DiagnosticDescriptor RemoveSuffixDescriptor = VSTHRD200UseAsyncNamingConventionAnalyzer.RemoveAsyncDescriptor;
[Fact]
public async Task TaskReturningMethodWithoutSuffix_GeneratesWarning()
{
@ -26,7 +31,53 @@ class Test {
}
";
var expected = Verify.Diagnostic().WithSpan(5, 10, 5, 13);
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 10, 5, 13);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
[Fact]
public async Task ValueTaskReturningMethodWithoutSuffix_GeneratesWarning()
{
var test = @"
using System.Threading.Tasks;
class Test {
ValueTask Foo() => default;
}
";
var withFix = @"
using System.Threading.Tasks;
class Test {
ValueTask FooAsync() => default;
}
";
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 15, 5, 18);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
[Fact]
public async Task ValueTaskOfTReturningMethodWithoutSuffix_GeneratesWarning()
{
var test = @"
using System.Threading.Tasks;
class Test {
ValueTask<int> Foo() => default;
}
";
var withFix = @"
using System.Threading.Tasks;
class Test {
ValueTask<int> FooAsync() => default;
}
";
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 20, 5, 23);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
@ -121,7 +172,7 @@ class Test {
}
";
var expected = Verify.Diagnostic().WithSpan(5, 10, 5, 13);
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 10, 5, 13);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
@ -158,8 +209,8 @@ class Test {
DiagnosticResult[] expected =
{
Verify.Diagnostic().WithSpan(5, 10, 5, 13),
Verify.Diagnostic().WithSpan(6, 10, 6, 13),
Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 10, 5, 13),
Verify.Diagnostic(AddSuffixDescriptor).WithSpan(6, 10, 6, 13),
};
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
@ -177,6 +228,52 @@ class Test {
await Verify.VerifyAnalyzerAsync(test);
}
[Fact]
public async Task VoidReturningMethodWithSuffix_GeneratesWarning()
{
var test = @"
class Test {
void FooAsync() { }
void Bar() => FooAsync();
}
";
var withFix = @"
class Test {
void Foo() { }
void Bar() => Foo();
}
";
var expected = Verify.Diagnostic(RemoveSuffixDescriptor).WithSpan(3, 10, 3, 18);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
[Fact]
public async Task BoolReturningMethodWithSuffix_GeneratesWarning()
{
var test = @"
class Test {
bool FooAsync() => false;
bool Bar() => FooAsync();
}
";
var withFix = @"
class Test {
bool Foo() => false;
bool Bar() => Foo();
}
";
var expected = Verify.Diagnostic(RemoveSuffixDescriptor).WithSpan(3, 10, 3, 18);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
[Fact]
public async Task TaskReturningMethodWithoutSuffix_ImplementsInterface_GeneratesWarningOnlyOnInterface()
{
@ -204,7 +301,7 @@ class Test : IFoo {
}
";
var expected = Verify.Diagnostic().WithSpan(5, 10, 5, 13);
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 10, 5, 13);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
@ -235,7 +332,7 @@ class Test : IFoo {
}
";
var expected = Verify.Diagnostic().WithSpan(5, 10, 5, 13);
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 10, 5, 13);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}
@ -266,7 +363,7 @@ class Test : MyBase {
}
";
var expected = Verify.Diagnostic().WithSpan(5, 26, 5, 29);
var expected = Verify.Diagnostic(AddSuffixDescriptor).WithSpan(5, 26, 5, 29);
await Verify.VerifyCodeFixAsync(test, expected, withFix);
}

Просмотреть файл

@ -62,7 +62,6 @@
<PackageReference Include="MicroBuild.VisualStudio" Version="$(MicroBuildVersion)" />
<PackageReference Include="GitLink" Version="3.2.0-unstable0014" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets" Label="MultilingualAppToolkit" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\v$(MultilingualAppToolkitVersion)\Microsoft.Multilingual.ResxResources.targets')" />
<Target Name="MATPrerequisite" BeforeTargets="PrepareForBuild" Condition="!Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets')" Label="MultilingualAppToolkit">

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="cs" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Použijte raději AsyncLazy&lt;T&gt;.</target>
<target state="translated">Přejmenování na {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Příponu Async použijte v názvech metod, které vrací Task.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Použití přípony Async pro asynchronní metody</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Vyvolání nebo zablokování asynchronního kódu v objektu pro vytváření hodnot Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; může způsobit zablokování.
Použijte raději AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="de" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Verwenden Sie stattdessen "AsyncLazy&lt;T&gt;".</target>
<target state="translated">In {0} umbenennen</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Verwenden Sie das Suffix "Async" in Namen von Methoden, die Tasks zurückgeben.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Verwenden Sie das Suffix "Async" für asynchrone Methoden</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Das Aufrufen oder Blockieren von asynchronem Code in einer Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt;-Wertfactory kann zu einem Deadlock führen.
Verwenden Sie stattdessen "AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;".</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="es" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; en su lugar.</target>
<target state="translated">Cambie el nombre a {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Use el sufijo "Async" en nombres de métodos de devolución de elementos Task</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Use el sufijo "Async" para métodos asincrónicos</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Invocar o bloquear en código asincrónico en un generador de valores Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; puede provocar interbloqueos.
Use en su lugar AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="fr" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Utilisez AsyncLazy&lt;T&gt; à la place</target>
<target state="translated">Renommer en {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Utilisez le suffixe "Async" dans les noms des méthodes retournant Task.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Utiliser le suffixe "Async" pour les méthodes asynchrones</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Les appels ou blocages sur le code async dans une fabrique de valeurs Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; peuvent faire l'objet d'un interblocage.
Utilisez plutôt AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="it" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ In alternativa, usare AsyncLazy&lt;T&gt;.</target>
<target state="translated">Rinomina in {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Usare il suffisso "Async" in nomi di metodi che restituiscono Task.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Usa suffisso "Async" per metodi asincroni</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">La chiamata o il blocco su codice asincrono in una factory di valori Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; può causare un deadlock.
In alternativa, usare AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="ja" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; instead.</source>
<target state="translated">{0} に名前を変更する</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">タスクを返すメソッドの名前に "Async" サフィックスを使用します。</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">非同期メソッドに "Async" サフィックスを使用する</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; 値ファクトリの非同期コードで呼び出しかブロックを実行すると、デッドロックを引き起こす可能性があります。
代わりに AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt; をご使用ください。</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="ko" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; instead.</source>
<target state="translated">{0}(으)로 이름 바꾸기</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Task-returning 메서드의 이름에 "Async" 접미사를 사용합니다.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">비동기 메서드에 "Async" 접미사 사용</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; 값 팩터리의 비동기 코드를 호출하거나 차단하면 교착 상태가 될 수 있습니다.
대신 AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;를 사용합니다.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="pl" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Zamiast tego używaj klasy AsyncLazy&lt;T&gt;.</target>
<target state="translated">Zmień nazwę na: {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">W nazwach metod zwracających obiekty Task używaj sufiksu „Async”.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">W przypadku metod asynchronicznych używaj sufiksu „Async”</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Wywołanie kodu asynchronicznego lub zablokowanie na nim w fabryce wartości Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; może spowodować zakleszczenie.
Zamiast tego użyj elementu AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="pt-BR" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Em vez disso, use AsyncLazy&lt;T&gt;.</target>
<target state="translated">Renomear para {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Use o sufixo "Async" em nomes de métodos que retornam tarefas.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Use o sufixo "Async" para métodos assíncronos</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">A invocação ou bloqueio em código assíncrono em um alocador de valor Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; pode causar um deadlock.
Use AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt; em vez disso.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="ru" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; instead.</source>
<target state="translated">Переименование в {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Используйте суффикс "Async" в названиях методов, возвращающих Task.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Использование суффикса "Async" в асинхронных методах</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Вызов или блокировка в асинхронном коде в методе ValueFactory Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; может вызвать взаимоблокировку.
Вместо этого используйте AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="tr" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Bunun yerine AsyncLazy&lt;T&gt; kullanın.</target>
<target state="translated">{0} olarak yeniden adlandırın</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">Task döndüren metotların adlarında “Async” kullanın.</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">Async metotları için "Async" sonekini kullanın</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">Bir Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; değer fabrikasında zaman uyumsuz kod çağrısı veya engellemesi çıkmaza yol açabilir.
Bunun yerine AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt; kullanın.</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="zh-Hans" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; instead.</source>
<target state="translated">重命名为 {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">在返回 Task 的方法的名称中使用“Async”后缀。</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">对异步方法使用“Async”后缀</target>
@ -218,6 +214,34 @@ Use AsyncLazy&lt;T&gt; instead.</source>
Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">在 Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; 值工厂中调用或阻止异步代码可能死锁。 请改用 AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en-US" target-language="zh-Hant" original="MICROSOFT.VISUALSTUDIO.THREADING.ANALYZERS/STRINGS.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
@ -104,10 +104,6 @@ Use AsyncLazy&lt;T&gt; instead.</source>
<target state="translated">重新命名為 {0}</target>
<note from="MultilingualBuild" annotates="source" priority="2">{0} is a method name.</note>
</trans-unit>
<trans-unit id="VSTHRD200_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of Task-returning methods.</source>
<target state="translated">請在 Task 傳回方法的名稱中使用 "Async" 尾碼。</target>
</trans-unit>
<trans-unit id="VSTHRD200_Title" translate="yes" xml:space="preserve">
<source>Use "Async" suffix for async methods</source>
<target state="translated">對非同步方法使用 "Async" 尾碼</target>
@ -219,6 +215,34 @@ Use AsyncLazy<it id="2" pos="open">&lt;T&gt;</it> instead.</source>
<target state="translated">在 Lazy&lt;it id="1" pos="open"&gt;&lt;T&gt;&lt;/it&gt; 值 Factory 中叫用或封鎖非同步程式碼可能會鎖死。
請改用 AsyncLazy&lt;it id="2" pos="open"&gt;&lt;T&gt;&lt;/it&gt;。</target>
</trans-unit>
<trans-unit id="VSTHRD200_AddAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Use "Async" suffix in names of methods that return an awaitable type.</source>
<target state="new">Use "Async" suffix in names of methods that return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD200_RemoveAsync_MessageFormat" translate="yes" xml:space="preserve">
<source>Avoid "Async" suffix in names of methods that do not return an awaitable type.</source>
<target state="new">Avoid "Async" suffix in names of methods that do not return an awaitable type.</target>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_False_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(false)</source>
<target state="new">Add .ConfigureAwait(false)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(false)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_CodeFix_True_Title" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(true)</source>
<target state="new">Add .ConfigureAwait(true)</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(true)" should not be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_MessageFormat" translate="yes" xml:space="preserve">
<source>Add .ConfigureAwait(bool) to your await expression.</source>
<target state="new">Add .ConfigureAwait(bool) to your await expression.</target>
<note from="MultilingualBuild" annotates="source" priority="2">".ConfigureAwait(bool)" and "await" should NOT be translated.</note>
</trans-unit>
<trans-unit id="VSTHRD111_Title" translate="yes" xml:space="preserve">
<source>Use ConfigureAwait(bool)</source>
<target state="new">Use ConfigureAwait(bool)</target>
<note from="MultilingualBuild" annotates="source" priority="2">"ConfigureAwait(bool)" is a reference and should NOT be translated.</note>
</trans-unit>
</group>
</body>
</file>

Просмотреть файл

@ -460,6 +460,51 @@ namespace Microsoft.VisualStudio.Threading.Analyzers {
}
}
/// <summary>
/// Looks up a localized string similar to Add .ConfigureAwait(false).
/// </summary>
internal static string VSTHRD111_CodeFix_False_Title {
get {
return ResourceManager.GetString("VSTHRD111_CodeFix_False_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add .ConfigureAwait(true).
/// </summary>
internal static string VSTHRD111_CodeFix_True_Title {
get {
return ResourceManager.GetString("VSTHRD111_CodeFix_True_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add .ConfigureAwait(bool) to your await expression..
/// </summary>
internal static string VSTHRD111_MessageFormat {
get {
return ResourceManager.GetString("VSTHRD111_MessageFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use ConfigureAwait(bool).
/// </summary>
internal static string VSTHRD111_Title {
get {
return ResourceManager.GetString("VSTHRD111_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use &quot;Async&quot; suffix in names of methods that return an awaitable type..
/// </summary>
internal static string VSTHRD200_AddAsync_MessageFormat {
get {
return ResourceManager.GetString("VSTHRD200_AddAsync_MessageFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Rename to {0}.
/// </summary>
@ -470,11 +515,11 @@ namespace Microsoft.VisualStudio.Threading.Analyzers {
}
/// <summary>
/// Looks up a localized string similar to Use &quot;Async&quot; suffix in names of Task-returning methods..
/// Looks up a localized string similar to Avoid &quot;Async&quot; suffix in names of methods that do not return an awaitable type..
/// </summary>
internal static string VSTHRD200_MessageFormat {
internal static string VSTHRD200_RemoveAsync_MessageFormat {
get {
return ResourceManager.GetString("VSTHRD200_MessageFormat", resourceCulture);
return ResourceManager.GetString("VSTHRD200_RemoveAsync_MessageFormat", resourceCulture);
}
}

Просмотреть файл

@ -85,9 +85,6 @@ Použijte raději AsyncLazy&lt;T&gt;.</value>
<value>Přejmenování na {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Příponu Async použijte v názvech metod, které vrací Task.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Použití přípony Async pro asynchronní metody</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Verwenden Sie stattdessen "AsyncLazy&lt;T&gt;".</value>
<value>In {0} umbenennen</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Verwenden Sie das Suffix "Async" in Namen von Methoden, die Tasks zurückgeben.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Verwenden Sie das Suffix "Async" für asynchrone Methoden</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Use AsyncLazy&lt;T&gt; en su lugar.</value>
<value>Cambie el nombre a {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Use el sufijo "Async" en nombres de métodos de devolución de elementos Task</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Use el sufijo "Async" para métodos asincrónicos</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Utilisez AsyncLazy&lt;T&gt; à la place</value>
<value>Renommer en {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Utilisez le suffixe "Async" dans les noms des méthodes retournant Task.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Utiliser le suffixe "Async" pour les méthodes asynchrones</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ In alternativa, usare AsyncLazy&lt;T&gt;.</value>
<value>Rinomina in {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Usare il suffisso "Async" in nomi di metodi che restituiscono Task.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Usa suffisso "Async" per metodi asincroni</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@
<value>{0} に名前を変更する</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>タスクを返すメソッドの名前に "Async" サフィックスを使用します。</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>非同期メソッドに "Async" サフィックスを使用する</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@
<value>{0}(으)로 이름 바꾸기</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Task-returning 메서드의 이름에 "Async" 접미사를 사용합니다.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>비동기 메서드에 "Async" 접미사 사용</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Zamiast tego używaj klasy AsyncLazy&lt;T&gt;.</value>
<value>Zmień nazwę na: {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>W nazwach metod zwracających obiekty Task używaj sufiksu „Async”.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>W przypadku metod asynchronicznych używaj sufiksu „Async”</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Em vez disso, use AsyncLazy&lt;T&gt;.</value>
<value>Renomear para {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Use o sufixo "Async" em nomes de métodos que retornam tarefas.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Use o sufixo "Async" para métodos assíncronos</value>
</data>

Просмотреть файл

@ -202,8 +202,8 @@ Use AsyncLazy&lt;T&gt; instead.</value>
<value>Rename to {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Use "Async" suffix in names of Task-returning methods.</value>
<data name="VSTHRD200_AddAsync_MessageFormat" xml:space="preserve">
<value>Use "Async" suffix in names of methods that return an awaitable type.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Use "Async" suffix for async methods</value>
@ -278,4 +278,23 @@ Use AsyncLazy&lt;T&gt; instead.</value>
<data name="VSTHRD110_Title" xml:space="preserve">
<value>Observe result of async calls</value>
</data>
<data name="VSTHRD200_RemoveAsync_MessageFormat" xml:space="preserve">
<value>Avoid "Async" suffix in names of methods that do not return an awaitable type.</value>
</data>
<data name="VSTHRD111_CodeFix_False_Title" xml:space="preserve">
<value>Add .ConfigureAwait(false)</value>
<comment>".ConfigureAwait(false)" should not be translated.</comment>
</data>
<data name="VSTHRD111_CodeFix_True_Title" xml:space="preserve">
<value>Add .ConfigureAwait(true)</value>
<comment>".ConfigureAwait(true)" should not be translated.</comment>
</data>
<data name="VSTHRD111_MessageFormat" xml:space="preserve">
<value>Add .ConfigureAwait(bool) to your await expression.</value>
<comment>".ConfigureAwait(bool)" and "await" should NOT be translated.</comment>
</data>
<data name="VSTHRD111_Title" xml:space="preserve">
<value>Use ConfigureAwait(bool)</value>
<comment>"ConfigureAwait(bool)" is a reference and should NOT be translated.</comment>
</data>
</root>

Просмотреть файл

@ -85,9 +85,6 @@
<value>Переименование в {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Используйте суффикс "Async" в названиях методов, возвращающих Task.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Использование суффикса "Async" в асинхронных методах</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@ Bunun yerine AsyncLazy&lt;T&gt; kullanın.</value>
<value>{0} olarak yeniden adlandırın</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>Task döndüren metotların adlarında “Async” kullanın.</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>Async metotları için "Async" sonekini kullanın</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@
<value>重命名为 {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>在返回 Task 的方法的名称中使用“Async”后缀。</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>对异步方法使用“Async”后缀</value>
</data>

Просмотреть файл

@ -85,9 +85,6 @@
<value>重新命名為 {0}</value>
<comment>{0} is a method name.</comment>
</data>
<data name="VSTHRD200_MessageFormat" xml:space="preserve">
<value>請在 Task 傳回方法的名稱中使用 "Async" 尾碼。</value>
</data>
<data name="VSTHRD200_Title" xml:space="preserve">
<value>對非同步方法使用 "Async" 尾碼</value>
</data>

Просмотреть файл

@ -146,6 +146,15 @@ namespace Microsoft.VisualStudio.Threading.Analyzers
internal static readonly IReadOnlyList<string> Namespace = Namespaces.SystemThreadingTasks;
}
internal static class ValueTask
{
internal const string TypeName = "ValueTask";
internal const string FullName = "System.Threading.Tasks." + TypeName;
internal static readonly IReadOnlyList<string> Namespace = Namespaces.SystemThreadingTasks;
}
internal static class CoClassAttribute
{
internal const string TypeName = nameof(System.Runtime.InteropServices.CoClassAttribute);

Просмотреть файл

@ -733,6 +733,33 @@ namespace Microsoft.VisualStudio.Threading.Analyzers
return SyntaxFactory.QualifiedName(result, simpleName);
}
internal static MemberAccessExpressionSyntax MemberAccess(IReadOnlyList<string> qualifiers, SimpleNameSyntax simpleName)
{
if (qualifiers == null)
{
throw new ArgumentNullException(nameof(qualifiers));
}
if (simpleName == null)
{
throw new ArgumentNullException(nameof(simpleName));
}
if (qualifiers.Count == 0)
{
throw new ArgumentException("At least one qualifier required.");
}
ExpressionSyntax result = SyntaxFactory.IdentifierName(qualifiers[0]);
for (int i = 1; i < qualifiers.Count; i++)
{
var rightSide = SyntaxFactory.IdentifierName(qualifiers[i]);
result = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, result, rightSide);
}
return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, result, simpleName);
}
internal static string GetFullName(ISymbol symbol)
{
if (symbol == null)

Просмотреть файл

@ -144,7 +144,10 @@
Task<Document> Fix(string fullyQualifiedMethod, IMethodSymbol methodSymbol, Lazy<ISymbol> cancellationTokenSymbol, CancellationToken cancellationToken)
{
var invocationExpression = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseName(fullyQualifiedMethod));
int typeAndMethodDelimiterIndex = fullyQualifiedMethod.LastIndexOf('.');
IdentifierNameSyntax methodName = SyntaxFactory.IdentifierName(fullyQualifiedMethod.Substring(typeAndMethodDelimiterIndex + 1));
ExpressionSyntax invokedMethod = Utils.MemberAccess(fullyQualifiedMethod.Substring(0, typeAndMethodDelimiterIndex).Split('.'), methodName);
var invocationExpression = SyntaxFactory.InvocationExpression(invokedMethod);
var cancellationTokenParameter = methodSymbol.Parameters.FirstOrDefault(IsCancellationTokenParameter);
if (cancellationTokenParameter != null && cancellationTokenSymbol.Value != null)
{

Просмотреть файл

@ -0,0 +1,56 @@
namespace Microsoft.VisualStudio.Threading.Analyzers
{
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
/// <summary>
/// Finds await expressions on <see cref="Task"/> that do not use <see cref="Task.ConfigureAwait(bool)"/>.
/// Also works on ValueTask.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class VSTHRD111UseConfigureAwaitAnalyzer : DiagnosticAnalyzer
{
public const string Id = "VSTHRD111";
internal static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(
id: Id,
title: Strings.VSTHRD111_Title,
messageFormat: Strings.VSTHRD111_MessageFormat,
helpLinkUri: Utils.GetHelpLink(Id),
category: "Usage",
defaultSeverity: DiagnosticSeverity.Hidden, // projects should opt IN to this policy
isEnabledByDefault: true);
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor);
/// <inheritdoc />
public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
context.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(this.AnalyzeAwaitExpression), SyntaxKind.AwaitExpression);
}
private void AnalyzeAwaitExpression(SyntaxNodeAnalysisContext context)
{
var awaitExpression = (AwaitExpressionSyntax)context.Node;
// Emit the diagnostic if the awaited expression is a Task or ValueTask.
// They obviously aren't using ConfigureAwait in that case since the awaited expression type would be a
// ConfiguredTaskAwaitable instead.
var awaitedTypeInfo = context.SemanticModel.GetTypeInfo(awaitExpression.Expression, context.CancellationToken);
if (awaitedTypeInfo.Type != null && awaitedTypeInfo.Type.BelongsToNamespace(Namespaces.SystemThreadingTasks) &&
(awaitedTypeInfo.Type.Name == Types.Task.TypeName || awaitedTypeInfo.Type.Name == Types.ValueTask.TypeName))
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, awaitExpression.Expression.GetLocation()));
}
}
}
}

Просмотреть файл

@ -0,0 +1,58 @@
namespace Microsoft.VisualStudio.Threading.Analyzers
{
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.VisualStudio.Threading;
[ExportCodeFixProvider(LanguageNames.CSharp)]
public class VSTHRD111UseConfigureAwaitCodeFix : CodeFixProvider
{
private static readonly ImmutableArray<string> ReusableFixableDiagnosticIds = ImmutableArray.Create(
VSTHRD111UseConfigureAwaitAnalyzer.Id);
/// <inheritdoc />
public override ImmutableArray<string> FixableDiagnosticIds => ReusableFixableDiagnosticIds;
/// <inheritdoc />
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
foreach (var diagnostic in context.Diagnostics)
{
var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var awaitedExpression = syntaxRoot.FindNode(diagnostic.Location.SourceSpan) as ExpressionSyntax;
Task<Document> ApplyFix(bool captureContext, CancellationToken cancellationToken)
{
ExpressionSyntax configuredAwaitExpression = SyntaxFactory.ParenthesizedExpression(
SyntaxFactory.InvocationExpression(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.ParenthesizedExpression(awaitedExpression).WithAdditionalAnnotations(Simplifier.Annotation),
SyntaxFactory.IdentifierName("ConfigureAwait")))
.AddArgumentListArguments(SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(captureContext ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression))))
.WithAdditionalAnnotations(Simplifier.Annotation);
return Task.FromResult(context.Document.WithSyntaxRoot(syntaxRoot.ReplaceNode(awaitedExpression, configuredAwaitExpression)));
}
context.RegisterCodeFix(CodeAction.Create(Strings.VSTHRD111_CodeFix_True_Title, ct => ApplyFix(true, ct), true.ToString()), diagnostic);
context.RegisterCodeFix(CodeAction.Create(Strings.VSTHRD111_CodeFix_False_Title, ct => ApplyFix(false, ct), false.ToString()), diagnostic);
}
}
}
}

Просмотреть файл

@ -22,10 +22,19 @@ namespace Microsoft.VisualStudio.Threading.Analyzers
internal const string MandatoryAsyncSuffix = "Async";
internal static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(
internal static readonly DiagnosticDescriptor AddAsyncDescriptor = new DiagnosticDescriptor(
id: Id,
title: Strings.VSTHRD200_Title,
messageFormat: Strings.VSTHRD200_MessageFormat,
messageFormat: Strings.VSTHRD200_AddAsync_MessageFormat,
helpLinkUri: Utils.GetHelpLink(Id),
category: "Style",
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);
internal static readonly DiagnosticDescriptor RemoveAsyncDescriptor = new DiagnosticDescriptor(
id: Id,
title: Strings.VSTHRD200_Title,
messageFormat: Strings.VSTHRD200_RemoveAsync_MessageFormat,
helpLinkUri: Utils.GetHelpLink(Id),
category: "Style",
defaultSeverity: DiagnosticSeverity.Warning,
@ -33,7 +42,8 @@ namespace Microsoft.VisualStudio.Threading.Analyzers
/// <inheritdoc />
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
Descriptor);
AddAsyncDescriptor,
RemoveAsyncDescriptor);
/// <inheritdoc />
public override void Initialize(AnalysisContext context)
@ -53,28 +63,38 @@ namespace Microsoft.VisualStudio.Threading.Analyzers
return;
}
if (!methodSymbol.Name.EndsWith(MandatoryAsyncSuffix))
bool shouldEndWithAsync = (methodSymbol.ReturnType.Name == nameof(Task) || methodSymbol.ReturnType.Name == "ValueTask") &&
methodSymbol.ReturnType.BelongsToNamespace(Namespaces.SystemThreadingTasks);
// Skip entrypoint methods since they must be called Main.
shouldEndWithAsync &= !Utils.IsEntrypointMethod(methodSymbol, context.Compilation, context.CancellationToken);
bool actuallyEndsWithAsync = methodSymbol.Name.EndsWith(MandatoryAsyncSuffix);
if (shouldEndWithAsync != actuallyEndsWithAsync)
{
if (methodSymbol.ReturnType.Name == nameof(Task) &&
methodSymbol.ReturnType.BelongsToNamespace(Namespaces.SystemThreadingTasks))
// Now that we have done the cheap checks to find that this method may deserve a diagnostic,
// Do deeper checks to skip over methods that implement API contracts that are controlled elsewhere.
if (methodSymbol.FindInterfacesImplemented().Any() || methodSymbol.IsOverride)
{
// Skip entrypoint methods since they must be called Main.
if (Utils.IsEntrypointMethod(methodSymbol, context.Compilation, context.CancellationToken))
{
return;
}
// Now that we have done the cheap checks to find that this method may deserve a diagnostic,
// Do deeper checks to skip over methods that implement API contracts that are controlled elsewhere.
if (methodSymbol.FindInterfacesImplemented().Any() || methodSymbol.IsOverride)
{
return;
}
return;
}
if (shouldEndWithAsync)
{
var properties = ImmutableDictionary<string, string>.Empty
.Add(VSTHRD200UseAsyncNamingConventionCodeFix.NewNameKey, methodSymbol.Name + MandatoryAsyncSuffix);
context.ReportDiagnostic(Diagnostic.Create(
Descriptor,
AddAsyncDescriptor,
methodSymbol.Locations[0],
properties));
}
else
{
var properties = ImmutableDictionary<string, string>.Empty
.Add(VSTHRD200UseAsyncNamingConventionCodeFix.NewNameKey, methodSymbol.Name.Substring(0, methodSymbol.Name.Length - MandatoryAsyncSuffix.Length));
context.ReportDiagnostic(Diagnostic.Create(
RemoveAsyncDescriptor,
methodSymbol.Locations[0],
properties));
}

Просмотреть файл

@ -81,7 +81,7 @@
TaskContinuationOptions.ExecuteSynchronously);
this.evt.Set();
setReturned.Set();
Assert.True(inlinedContinuation.Wait(AsyncDelay));
Assert.True(inlinedContinuation.Wait(ExpectedTimeout));
}
/// <summary>

Просмотреть файл

@ -1450,7 +1450,7 @@
}).GetAwaiter().GetResult();
}
[StaFact]
[StaFact, Trait("TestCategory", "FailsInCloudTest")]
public void UpgradeableReadLockAsyncSynchronousReleaseAllowsOtherUpgradeableReaders()
{
var testComplete = new ManualResetEventSlim(); // deliberately synchronous

5
src/global.json Normal file
Просмотреть файл

@ -0,0 +1,5 @@
{
"sdk": {
"version": "2.1.300"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositorypath" value="packages" />
<add key="repositorypath" value="..\packages" />
</config>
<packageSources>
<clear />

Просмотреть файл

@ -4,10 +4,5 @@
"publicReleaseRefSpec": [
"^refs/heads/master$", // we release out of master
"^refs/heads/v\\d+(?:\\.\\d+)?$" // we also release out of vNN branches
],
"cloudBuild": {
"buildNumber": {
"enabled": true
}
}
]
}