Merge pull request #130 from mjrousos/mikerou/DelegateBeginInvoke

Delegate.BeginInvoke/EndInvoke analyzer
This commit is contained in:
Immo Landwerth 2019-04-12 11:45:44 -07:00 коммит произвёл GitHub
Родитель 532b760d5e dde8b054f8
Коммит e2a658de3b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 453 добавлений и 7 удалений

41
docs/PC004.md Normal file
Просмотреть файл

@ -0,0 +1,41 @@
# PC004: Delegate.BeginInvoke and EndInvoke are Unsupported on .NET Core
## Cause
You're using the [Asynchronous Programming Model](https://docs.microsoft.com/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously) to invoke a delegate (via the `BeginInvoke` method) which is unsupported on .NET Core.
## Rule description
The `BeginInvoke` and `EndInvoke` methods automatically generated for delegate types at compile-time are not supported by .NET Core. Calling these methods will throw a `NotSupportedException`. Task-based [TPL](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl) patterns should be used instead.
## How to fix violations
Remove calls to `BeginInvoke` and `EndInvoke`. Replace `IAsyncResult` usage with `Task`-based patterns, instead. For example:
```CSharp
delegate int WorkDelegate(int arg);
...
WorkDelegate del = DoWork;
// Schedule the work using a Task
Console.WriteLine("Starting with Task.Run");
var workTask = Task.Run(() => DoWork(11));
// Optionally, we can specify a continuation delegate
// to execute when DoWork has finished
var followUpTask = workTask.ContinueWith(TaskCallback);
// This writes output to the console while DoWork is running in the background
Console.WriteLine("Waiting on work...");
// We await the task instead of calling EndInvoke
var ret = await workTask;
await folowUpTask;
```
## When to suppress warnings
These methods are never usable on .NET Core. Suppress the warning only if:
1. These code paths are only used while running on .NET Framework.
2. The analyzer has mistakenly flagged an API that is not a call to a compiler-generated `BeginInvoke`/`EndInvoke` APM method.

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

@ -59,6 +59,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{6F07EE72-A
docs\PC001.md = docs\PC001.md
docs\PC002.md = docs\PC002.md
docs\PC003.md = docs\PC003.md
docs\PC004.md = docs\PC004.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{09FF4C67-A805-490B-9323-4F60882875B6}"

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

@ -0,0 +1,160 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke;
using Microsoft.DotNet.Analyzers.Compatibility.Tests.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.DotNet.Analyzers.Compatibility.Tests
{
public class BeginInvokeEndInvokeAnalyzerTests : CSharpDiagnosticTest
{
protected override DiagnosticAnalyzer CreateAnalyzer()
{
return new BeginInvokeEndInvokeAnalyzer();
}
[Fact]
public void DoesNotTrigger_WhenDocumentEmpty()
{
AssertNoMatch(string.Empty);
}
[Fact]
public void DoesNotTriggerForCallsToOtherMethods()
{
var source = @"
delegate void TestDelegate(int i);
class Program
{
static void TestMethod2(int i) {}
static void BeginInvoke() {}
static void TestMethod(int i)
{
TestDelegate t = TestMethod;
Program.BeginInvoke();
Program.TestMethod2(1);
}
}
";
AssertNoMatch(source);
}
[Fact]
public void DoesNotFailWhenNamespaceMissing()
{
var source = @"
class BaseClass {}
class Program : BaseClass
{
static void BeginInvoke() {}
static void TestMethod(int i)
{
Program.BeginInvoke();
}
}
";
AssertNoMatch(source);
}
[Fact]
public void TriggersForBeginInvoke()
{
var source = @"
delegate void TestDelegate(int i);
class Program
{
static void TestMethod(int i)
{
TestDelegate t = TestMethod;
var result = {{t.BeginInvoke(5, null, null)}};
}
}
";
var expected = "PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.";
AssertMatch(source, expected);
}
[Fact]
public void TriggersForEndInvoke()
{
var source = @"
delegate void TestDelegate(int i);
class Program
{
static void TestMethod(int i)
{
TestDelegate t = TestMethod;
var result = {{t.BeginInvoke(5, null, null)}};
{{t.EndInvoke(result)}};
}
}
";
var expected = @"
PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.
PC004: EndInvoke is unsupported on .NET Core. Use Tasks instead.
";
AssertMatch(source, expected);
}
[Fact]
public void TriggersForFuzzyMatches()
{
var source = @"
delegate void TestDelegate(int i);
class Program
{
static void TestMethod(int i)
{
TestDelegate t = TestMethod;
var result = {{t.BeginInvoke()}};
{{t.EndInvoke(foo)}};
}
}
";
var expected = @"
PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.
PC004: EndInvoke is unsupported on .NET Core. Use Tasks instead.
";
AssertMatch(source, expected);
}
[Fact]
public void DoesNotTriggerForNonDelegateFuzzyMatches()
{
var source = @"
delegate void TestDelegate(int i);
class Program
{
static void TestMethod(int i)
{
var t = GetObject();
var result = t.BeginInvoke();
t.EndInvoke(foo);
}
}
";
AssertNoMatch(source);
}
}
}

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

@ -0,0 +1,84 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Linq;
namespace Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke
{
// Looks for use of BeginInvoke or EndInvoke methods on types derived from System.Delegate
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class BeginInvokeEndInvokeAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "PC004";
private const string Category = "Usage";
private const string HelpLink = "https://github.com/dotnet/platform-compat/blob/master/docs/" + DiagnosticId + ".md";
private const string TargetTypeFullName = "System.Delegate";
private readonly string[] MethodNames = { "BeginInvoke", "EndInvoke" };
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.BeginInvokeEndInvokeAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.BeginInvokeEndInvokeAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, helpLinkUri: HelpLink);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeInvocationExpression, SyntaxKind.InvocationExpression);
}
private void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
{
// Bail out if the syntax doesn't include a member access expression for some reason
if (!(context.Node is InvocationExpressionSyntax invocationExpression &&
invocationExpression.Expression is MemberAccessExpressionSyntax memberAccessExpression))
return;
// Bail out if the member access expression doesn't correspond to a method symbol
var symbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpression);
if (!(symbolInfo.Symbol is IMethodSymbol methodSymbol))
{
// In some cases, the member access expression's symbol won't be definitively known
// (if, for example, the argument passed to EndInvoke isn't definitely known yet), so
// check candidate symbols and use that if there's only one candidate method there.
methodSymbol = symbolInfo.CandidateSymbols.SingleOrDefault(s => s is IMethodSymbol) as IMethodSymbol;
if (methodSymbol == null)
return;
}
// Only analyze methods with an appropriate name
if (!MethodNames.Contains(methodSymbol.Name))
return;
// Only analyze methods on Delegate types
if (!TypeIsDescendentOf(methodSymbol.ContainingType, typeof(Delegate)))
return;
context.ReportDiagnostic(Diagnostic.Create(Rule, invocationExpression.GetLocation(), methodSymbol.Name));
}
private bool TypeIsDescendentOf(INamedTypeSymbol containingType, Type targetType)
{
// If the type has no base, return false
if (containingType.BaseType == null)
{
return false;
}
// If the type's parent is the targetType, return true
if (TargetTypeFullName.Equals(GetFullName(containingType.BaseType)))
{
return true;
}
// Otherwise, recurse and check the parent's parent
return TypeIsDescendentOf(containingType.BaseType, targetType);
}
private string GetFullName(INamedTypeSymbol type) =>
$"{type.ContainingNamespace.Name}.{type.Name}";
}
}

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

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke;
using Microsoft.DotNet.Analyzers.Compatibility.Deprecated;
using Microsoft.DotNet.Analyzers.Compatibility.Exceptions;
using Microsoft.DotNet.Analyzers.Compatibility.ModernSdk;
@ -30,6 +31,7 @@ namespace Microsoft.DotNet.Analyzers.Compatibility.Fixes
result.Add(ModernSdkAnalyzer.DiagnosticId);
result.Add(Net461Analyzer.DiagnosticId);
result.AddRange(DeprecatedAnalyzer.GetDescriptors().Select(d => d.Id));
result.Add(BeginInvokeEndInvokeAnalyzer.DiagnosticId);
return result.ToImmutableArray();
}
}

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

@ -70,6 +70,24 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
}
}
/// <summary>
/// Looks up a localized string similar to {0} is unsupported on .NET Core. Use Tasks instead..
/// </summary>
internal static string BeginInvokeEndInvokeAnalyzerMessageFormat {
get {
return ResourceManager.GetString("BeginInvokeEndInvokeAnalyzerMessageFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core.
/// </summary>
internal static string BeginInvokeEndInvokeAnalyzerTitle {
get {
return ResourceManager.GetString("BeginInvokeEndInvokeAnalyzerTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Browse to {0}.
/// </summary>
@ -81,13 +99,14 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
/// <summary>
/// Looks up a localized string similar to DocId,Namespace,Type,Member,DiagnosticIds
///M:System.Environment.get_OSVersion,System,Environment,get_OSVersion(),DE0009
///F:System.PlatformID.MacOSX,System,PlatformID,MacOSX,DE0007
///F:System.PlatformID.Win32S,System,PlatformID,Win32S,DE0007
///F:System.PlatformID.Win32Windows,System,PlatformID,Win32Windows,DE0007
///F:System.PlatformID.WinCE,System,PlatformID,WinCE,DE0007
///F:System.PlatformID.Xbox,System,PlatformID,Xbox,DE0007
///T:System.Collections.ArrayList,System.Collections,ArrayList,,DE0006
///T:System.Collections.CaseInsensitiveComparer,System.Collections,CaseInsensitiveComparer,,DE000 [rest of string was truncated]&quot;;.
///M:System.Collections.ArrayList.#ctor,System.Collections,ArrayList,.ctor(),DE0006
///M:S [rest of string was truncated]&quot;;.
/// </summary>
internal static string Deprecated {
get {
@ -133,8 +152,10 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
/// <summary>
/// Looks up a localized string similar to DocId,Namespace,Type,Member,linux,osx,win
///&quot;M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)&quot;,Microsoft.CSharp.RuntimeBinder,RuntimeBinderException,&quot;.ctor(SerializationInfo, StreamingContext)&quot;,X,X,X
///&quot;M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)&quot;,Microsoft.CSharp.RuntimeBinder, [rest of string was truncated]&quot;;.
///M:Microsoft.Win32.PowerModeChangedEventArgs.#ctor(Microsoft.Win32.PowerModes),Microsoft.Win32,PowerModeChangedEventArgs,.ctor(PowerModes),X,X,
///M:Microsoft.Win32.PowerModeChangedEventArgs.get_Mode,Microsoft.Win32,PowerModeChangedEventArgs,get_Mode(),X,X,
///&quot;M:Microsoft.Win32.Registry.GetValue(System.String,System.String,System.Object)&quot;,Microsoft.Win32,Registry,&quot;GetValue(String, String, Object)&quot;,X,X,
///&quot;M:Microsoft.Win32.Registry.SetValue(System.String,System.String,S [rest of string was truncated]&quot;;.
/// </summary>
internal static string Exceptions {
get {
@ -185,12 +206,11 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
/// <summary>
/// Looks up a localized string similar to DocId,Namespace,Type,Member
///M:System.AppContext.GetData(System.String),System,AppContext,GetData(String)
///P:System.AppContext.TargetFrameworkName,System,AppContext,TargetFrameworkName
///M:System.AppContext.get_TargetFrameworkName,System,AppContext,get_TargetFrameworkName()
///T:System.StringNormalizationExtensions,System,StringNormalizationExtensions,
///T:System.Data.Common.DbColumn,System.Data.Common,DbColumn,
///T:System.Data.Common.DbDataReaderExtensions,System.Data.Common,DbDataReaderExtensions,
///T:System.Data.Common.IDbColumnSchemaGenerator,System.Data.Common,IDbColumnSchemaGenerator,
///T:System [rest of string was truncated]&quot;;.
///T:System.Data.Common.IDbColumnSchemaGenerator,System.Data.Common,IDbColumnSchemaGenerator, [rest of string was truncated]&quot;;.
/// </summary>
internal static string Net461 {
get {

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

@ -120,6 +120,14 @@
<data name="AboutDiagnosticFormatString" xml:space="preserve">
<value>About {0}</value>
</data>
<data name="BeginInvokeEndInvokeAnalyzerMessageFormat" xml:space="preserve">
<value>{0} is unsupported on .NET Core. Use Tasks instead.</value>
<comment>The format-able message the diagnostic displays.</comment>
</data>
<data name="BeginInvokeEndInvokeAnalyzerTitle" xml:space="preserve">
<value>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</value>
<comment>The title of the diagnostic.</comment>
</data>
<data name="BrowseToUrlFormat" xml:space="preserve">
<value>Browse to {0}</value>
</data>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>

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

@ -57,6 +57,16 @@
<target state="new">Report an issue with {0}</target>
<note />
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
<note>The format-able message the diagnostic displays.</note>
</trans-unit>
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
<note>The title of the diagnostic.</note>
</trans-unit>
</body>
</file>
</xliff>