Problem
The MauiCommunityToolkitMvvmEventsBinder has some code that wraps AsyncRelayCommand execution in a transaction... however it does something unexpected.
The first time this event triggers, there's no transaction on the scope and so a transaction gets created here.
Later, when the relay command finishes, the associated transaction is finished, which should reset the transaction on the scope (setting this to null):
|
scope.ResetTransaction(this); |
And immediately after span.Finish() is called, this is the case (scope.Transaction has been reset).
However when the code runs for subsequent AsyncRelayCommands, for some reason the (completed) transaction is back on the scope again!
We created a workaround in that PR but we really should dig into this to understand what's going on.
Initial analysis
Originally posted by @jamescrosswell in #4125 (comment)
I don't quite understand what's happening yet, but most stuff on the Scope is global in MAUI cause we always set IsGlobalMode = true for MAUI apps. Scope.Transaction is an exception:
|
private readonly AsyncLocal<ITransactionTracer?> _transaction = new(); |
AsyncLocal<T> has a constructor overload that lets you wire up a ValueChanged event handler, which I did for Scope._transaction and there is definitely something very odd going on.
Putting a breakpoint in there, the first time it triggers is when our OnPropertyChanged fires, assigning Scope.Transaction for the first time (with the new transaction):

The it fires twice more with args.ThreadContextChanged == true:


Then it fires again from our OnPropertyChanged event handler when the command finishes running (this is finishing the transaction and resetting Scope.Transaction = null:

However immediately after that there's a thread context change again and the property gets restored to a non-null value!!! 🐛 🐞 😞

Problem
The
MauiCommunityToolkitMvvmEventsBinderhas some code that wrapsAsyncRelayCommandexecution in a transaction... however it does something unexpected.The first time this event triggers, there's no transaction on the scope and so a transaction gets created here.
Later, when the relay command finishes, the associated transaction is finished, which should reset the transaction on the scope (setting this to null):
sentry-dotnet/src/Sentry/TransactionTracer.cs
Line 399 in 8abc247
And immediately after
span.Finish()is called, this is the case (scope.Transactionhas been reset).However when the code runs for subsequent AsyncRelayCommands, for some reason the (completed) transaction is back on the scope again!
We created a workaround in that PR but we really should dig into this to understand what's going on.
Initial analysis
Originally posted by @jamescrosswell in #4125 (comment)
I don't quite understand what's happening yet, but most stuff on the Scope is global in MAUI cause we always set
IsGlobalMode = truefor MAUI apps.Scope.Transactionis an exception:sentry-dotnet/src/Sentry/Scope.cs
Line 203 in 8abc247
AsyncLocal<T>has a constructor overload that lets you wire up a ValueChanged event handler, which I did forScope._transactionand there is definitely something very odd going on.Putting a breakpoint in there, the first time it triggers is when our
OnPropertyChangedfires, assigningScope.Transactionfor the first time (with the new transaction):The it fires twice more with


args.ThreadContextChanged == true:Then it fires again from our

OnPropertyChangedevent handler when the command finishes running (this is finishing the transaction and resettingScope.Transaction = null:However immediately after that there's a thread context change again and the property gets restored to a non-null value!!! 🐛 🐞 😞