diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/Microsoft.VisualStudio.Threading.Analyzers.CSharp.csproj b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/Microsoft.VisualStudio.Threading.Analyzers.CSharp.csproj
index 1895f9ed4..36c64f7f1 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/Microsoft.VisualStudio.Threading.Analyzers.CSharp.csproj
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/Microsoft.VisualStudio.Threading.Analyzers.CSharp.csproj
@@ -6,7 +6,7 @@
false
-
+
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD010MainThreadUsageAnalyzer.cs b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD010MainThreadUsageAnalyzer.cs
index 6c2a6bdea..191d0e2b1 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD010MainThreadUsageAnalyzer.cs
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/VSTHRD010MainThreadUsageAnalyzer.cs
@@ -148,6 +148,9 @@ public override void Initialize(AnalysisContext context)
compilationStartContext.RegisterOperationAction(Utils.DebuggableWrapper(c => this.AddToCallerCalleeMap(c, callerToCalleeMap)), OperationKind.Invocation);
compilationStartContext.RegisterOperationAction(Utils.DebuggableWrapper(c => this.AddToCallerCalleeMap(c, callerToCalleeMap)), OperationKind.PropertyReference);
+ // Strictly speaking, this will miss access to the underlying field, but there's no method to put in the map in that case
+ compilationStartContext.RegisterOperationAction(Utils.DebuggableWrapper(c => this.AddToCallerCalleeMap(c, callerToCalleeMap)), OperationKind.EventAssignment);
+
compilationStartContext.RegisterCompilationEndAction(compilationEndContext =>
{
Dictionary>? calleeToCallerMap = CreateCalleeToCallerMap(callerToCalleeMap);
@@ -253,6 +256,17 @@ private void AddToCallerCalleeMap(OperationAnalysisContext context, Dictionary
-
+
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic.csproj b/src/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic.csproj
index 20497126d..a0090e9d1 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic.csproj
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic/Microsoft.VisualStudio.Threading.Analyzers.VisualBasic.csproj
@@ -6,7 +6,7 @@
false
-
+
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj b/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
index 627921ce6..871643b17 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
@@ -22,7 +22,7 @@
-
+
all
diff --git a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
index 05cec43fc..dc9b8057f 100644
--- a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
+++ b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
@@ -1630,6 +1630,39 @@ void Foo()
await Verify.VerifyAnalyzerAsync(test, expected);
}
+ [Fact]
+ public async Task Events()
+ {
+ var test = @"
+namespace TestNS
+{
+ interface SomeInterface
+ {
+ event System.Action UIEventName;
+ }
+}
+
+class A
+{
+ void Handler()
+ {
+ }
+
+ void Test(TestNS.SomeInterface i)
+ {
+ i.UIEventName += this.Handler;
+ i.UIEventName -= this.Handler;
+ }
+}
+";
+ DiagnosticResult[] expected =
+ {
+ Verify.Diagnostic(DescriptorSync).WithSpan(18, 11, 18, 22).WithArguments("SomeInterface", "Test.VerifyOnUIThread"),
+ Verify.Diagnostic(DescriptorSync).WithSpan(19, 11, 19, 22).WithArguments("SomeInterface", "Test.VerifyOnUIThread"),
+ };
+ await Verify.VerifyAnalyzerAsync(test, expected);
+ }
+
///
/// Field initializers should never have thread affinity since the thread cannot be enforced before the code is executed,
/// since initializers run before the user-defined constructor.