You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes: #7590
Fix the remaining `[SupportedOSPlatform]` warnings in manually bound
code. Other issues we were previously seeing appear to have been a
bug in earlier .NET 8 previews.
In the simple cases, we just needed to add `[SupportedOSPlatform]` to
our hand-written methods.
For more complicated cases, we resolve the remaining CA1416 and
CA1422 warnings by using `[SuppressMessage]`.
Rationale: The constructors for
[`java.lang.Boolean(boolean)`][0], [`java.lang.Integer(int)`][2],
etc., were marked as `@Deprecated` in API-33, with a suggestion to
instead use [`Booleal.valueOf(boolean)`][1],
[`Integer.valueOf(int)`][3], etc. We *cannot* follow this advice in
multiple places of our infrastructure, due to a desire to reduce
JNI Global Reference (GREF) usage and preserve thread safety.
Imagine that two threads execute the following code:
using (var val = Java.Lang.Integer.ValueOf(42)) {
val.FloatValue();
}
Because we attempt to preserve object identity -- if
multiple Java calls of `Integer.valueOf(42)` return the same
instance, then multiple C# calls of `Integer.ValueOf(42)` should
likewise return the same instance -- we may be dealing with mutable
shared state!
1. Thread 1: calls C# `Integer.ValueOf(42)`, calls
Java `Integer.valueOf(42)`, `Java.Lang.Integer` wrapper instance
created and registered.
2. Thread 1: calls `val.FloatValue()`
3. Thread 2: calls `Integer.ValueOf(42)`, gets wrapper instance
created in (1)
4. Thread 1: calls `val.Dispose()`
5. Thread 2: calls `val.FloatValue()`.
This throws an `ObjectDisposedException`, because of (4).
We thus have a conundrum: if we replace all usage of the e.g.
`Integer(int)` constructor with calls to `Integer.ValueOf(int)`,
*we can no longer* call `.Dispose()` on the value. This willl
increase GREF usage, *but could be an overall improvement* as it may
also result in fewer Java-side `Integer` instances being created.
Without additional testing and microbenchmarks, it's hard to say
which is actually "better".
In the absense of such a micobenchmark, resolve some of the CA1416
and CA1422 warnings by using `[SuppressMessage]`.
[0]: https://developer.android.com/reference/java/lang/Boolean#Boolean(boolean)
[1]: https://developer.android.com/reference/java/lang/Boolean#valueOf(boolean)
[2]: https://developer.android.com/reference/java/lang/Integer#Integer(int)
[3]: https://developer.android.com/reference/java/lang/Integer#valueOf(int)
0 commit comments