-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent Android timer from adding multiple callbacks #16078
Conversation
|
||
_handler.PostDelayed(_runnable, (long)Interval.TotalMilliseconds); | ||
|
||
if (!OperatingSystem.IsAndroidVersionAtLeast(29)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what changed in API level 29?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hasCallbacks()
method did not exist until API 29.
https://developer.android.com/reference/android/os/Handler#hasCallbacks(java.lang.Runnable)
Could you help me understand how the Post, Stop, and callbacks logic all works? |
The point of the timer is to allow the developer to say "call this method in X milliseconds". The callback is the method they want to call. All of the platforms provide some sort built-in mechanism to do this; the So you create a timer with a callback, and you set the interval (how long to wait before calling it). You can set it to repeat, or you can turn off repetition and it will run just once. Then you call Start() to get the timer ticking. When "interval" milliseconds have passed, the callback method will be called. If repetition is turned on, the timer will start counting down again. Otherwise, it will stop. You can also call Stop() at any time to stop the timer. On Android, the built-in mechanism is called a Handler. A Handler manages a queue of messages/callbacks that are processed by a Looper (which just runs in a loop, checking to see if there's work to do). The Handler "posts" work items to the queue. It can post at the front of the queue (run immediately), at the end of the queue (get to this when you get to it), or at a specific time in the future (which is what the DispatcherTimer uses). |
|
||
// We only need to worry about tracking this if we're below API 29; after that, | ||
// we can just ask the Handler with the HasCallBacks() method. | ||
_hasCallbacks = hasCallbacks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to worry about thread safety here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. Do you have a scenario where you think it would be a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two windows, but that will have 2 dispatchers right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There may be the case where you use the timer from 2 threads that could cause issues. But I am not sure if the hasCallbacks
method is itself thread safe...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this code need to be "thread safe"? None of our other DispatcherTimer implementations are.
And the only "thread safety" worry would be if someone decided to operate on the same DispatcherTimer from multiple threads. I would argue that if someone is going to do that, it's up to them to make sure that whatever thing they're doing is "thread safe". They wanna do something weird, they can add their own lock()
statements.
(To be clear, this code is not "thread safe" in the sense that you could theoretically (it's really hard to do) have two threads attempting to call Start()
at the same time and get a weird double-post behavior, and the pre-API 29 version would behave differently than the post-API 29 version. You could also cause problems by changing the values of IsRepeating and Interval from multiple threads, but that was a problem before this change and also with all of our other implementations of DispatcherTimer.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with all the above. We don't need to do locks ourselves.
* Add swipe for uitests * Bump the androidx group with 1 update (#16474) Bumps the androidx group with 1 update: [Xamarin.AndroidX.RecyclerView](https://github.com/xamarin/AndroidX). - [Commits](https://github.com/xamarin/AndroidX/commits) --- updated-dependencies: - dependency-name: Xamarin.AndroidX.RecyclerView dependency-type: direct:production update-type: version-update:semver-patch dependency-group: androidx ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Document Element (#16299) * Begin doc progress * Document element * More explicit interface implementations * Address PR feedback * Document interfaces + delete xml * whitespace * Prevent compile issues * Document IElementController (and mark as obsolete) * Remove Obsolete attribute from IElementController This would break the build in various places - and would go out of scope of the PR * Document IVusalElementController Apparently is only for internal use. We can't make it private so the only choice is to mark everything as for internal use only * Prevent mdoc from breaking You can't really cref a namespace * Fixed other crefs * Address Dave's feedback * Move powershell pack script into cake (#16588) * 'pwsh' is broken on net8 PowerShell/PowerShell#19679 * Remove the script * oops * Fix Graphics Font comparison method (#15985) * Fix the issue * Added more tests * Updated Impl * [WinUI] Implement PointerPressed and PointerReleased (#16213) * Implement on Windows and add unit tests * Update src/Controls/src/Core/PointerGestureRecognizer.cs Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com> --------- Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com> * [X] Optimize OnPlatform element syntax (#5611) * [X] Optimize OnPlatform element syntax - fixes #5583 * Auto-format source code * don't generate x:Name for removed OnPlatforms * Update src/Controls/src/SourceGen/Controls.SourceGen.csproj Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com> * fix string comparison --------- Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com> * [Housekeeping] Add 8.0 preview 7 (#16613) also adds a checkbox to make it clear if this is a regression or not * [X] Support DynResources as AppThemeBinding values (#16597) Because, you know, why not ? It could be useful - fixes #13619 * [main] Update dependencies from dotnet/xharness (#16600) * Update dependencies from https://github.com/dotnet/xharness build 20230807.2 Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 8.0.0-prerelease.23403.1 -> To Version 8.0.0-prerelease.23407.2 * Run device tests on 16.4 * Force to 16.4 * Skip test that fails on iOS --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Rui Marinho <me@ruimarinho.net> * Adds prompts when creating a new page. (#16331) * Adds prompts when creating a new page. * Updates description as per suggested PR comments * [ios] fix memory leak in GraphicsView (#16605) Context: #16346 This addresses the memory leak discovered by: src/Core/src/Platform/iOS/PlatformTouchGraphicsView.cs(12,29): error MA0002: Member '_hoverGesture' could cause memory leaks in an NSObject subclass. Remove the member, store the value as a WeakReference, or add the [UnconditionalSuppressMessage("Memory", "MA0002")] attribute with a justification as to why the member will not leak. I could reproduce a leak in `MemoryTests.cs`: ++[InlineData(typeof(GraphicsView))] public async Task HandlerDoesNotLeak(Type type) Solved the problem by fixing two places: * `PlatformTouchGraphicsView` now stores the `IGraphicsView` as a `WeakReference`. * A `UIHoverGestureRecognizerProxy` is used for callbacks to the `UIHoverGestureRecognizer`. * [create-pull-request] automated change (#16592) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Setting binding on Label doesn't set text to incoming binding (#16410) * Test demonstrating binding issue * [C] SetBinding overrides SetValue, but only when the value is set * - reenable tests --------- Co-authored-by: Stephane Delcroix (HE/HIM) (from Dev Box) <stdelc@microsoft.com> * Added DeviceTest to validate CharacterSpacing on iOS Button (#16603) * Use runtime check for setting WKWebView inspectable flag (#16631) * Use runtime check * Remove private * Add back line * Line endings? * Use System.OperatingSystem * Update src/BlazorWebView/src/Maui/iOS/BlazorWebViewHandler.iOS.cs Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> --------- Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> * [Housekeeping] Fix broken bug template (#16643) * [Housekeeping] Fix broken bug template checkbox <> checkboxes * Update bug-report.yml * Update bug-report.yml * Implement Additional PointerGestureRecognizer Platform Arguments (#16426) * Pointer Platform Event Args * remove extension and use property instead * make ctor internal * nullable consistency, spelling, and private setter * Public API changes and remove nullable windows routedargs * uitests part 1 * only run ui tests on windows and mac * move device conditional to test * Change the tests to Pointer Tests for more reusability * Add documentation * Add extension method for ignoring platforms * Update the documentation * Change platform specific docs * [C] fix Specificity for VSM (#16404) * [C] fix Specificity for VSM - fixes #11204 * remove skipped test * Prevent Android timer from adding multiple callbacks; (#16078) Fixes #10257 * [Housekeeping] Remove checkboxes from bug template (#16650) I did not realize that they would be editable tasks on the issue. Replaced with a dropdown. Also reordered the versions to be the most likely default options to speed up the reporting process. * [Android] Fix SwipeView not swiping using Label as direct content (#14824) * Fix Android SwipeView not swiping using Label as Content * Refactoring code * Added sample to validate 6154 --------- Co-authored-by: Javier Suárez <6755973+jsuarezruiz@users.noreply.github.com> * Locate MAUI View for PlatformView (#16463) * Locate xplat view from platformview * - dispatcher * - fix layout comparison on xunit * - PR review comments * - tizen fix * Bump the aspnetcore group with 7 updates (#16634) Bumps the aspnetcore group with 7 updates: | Package | Update | | --- | --- | | [Microsoft.AspNetCore.Authorization](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.AspNetCore.Components.WebView](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.JSInterop](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.AspNetCore.Components.Web](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.AspNetCore.Authentication.Facebook](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.AspNetCore.Authentication.Google](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | | [Microsoft.AspNetCore.Authentication.MicrosoftAccount](https://github.com/dotnet/aspnetcore) | 7.0.9 to 7.0.10 | Updates `Microsoft.AspNetCore.Authorization` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.AspNetCore.Components.WebView` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.JSInterop` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.AspNetCore.Components.Web` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.AspNetCore.Authentication.Facebook` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.AspNetCore.Authentication.Google` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) Updates `Microsoft.AspNetCore.Authentication.MicrosoftAccount` from 7.0.9 to 7.0.10 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](dotnet/aspnetcore@v7.0.9...v7.0.10) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Authorization dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.AspNetCore.Components.WebView dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.JSInterop dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.AspNetCore.Components.Web dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.AspNetCore.Authentication.Facebook dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.AspNetCore.Authentication.Google dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore - dependency-name: Microsoft.AspNetCore.Authentication.MicrosoftAccount dependency-type: direct:production update-type: version-update:semver-patch dependency-group: aspnetcore ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [create-pull-request] automated change (#16655) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [ios] fix memory leak in SwipeItem (#16614) Context: #16346 This addresses the memory leak discovered by: src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs(10,30): error MA0001: Event 'FrameChanged' could cause memory leaks in an NSObject subclass. Remove the event or add the [UnconditionalSuppressMessage("Memory", "MA0001")] attribute with a justification as to why the event will not leak. I could reproduce the leak with a custom test in `SwipeViewTests`. Solved the problem by introducing `SwipeItemButtonProxy` with the same pattern from other PRs. * [ios/catalyst] fix memory leak in DatePicker (#16589) Context: #16346 This addresses the memory leak discovered by: src/Core/src/Platform/iOS/MauiDatePicker.cs(37,27): error MA0003: Subscribing to events with instance method 'OnValueChanged' could cause memory leaks in an NSObject subclass. Remove the subscription or convert the method to a static method. I could reproduce a leak in `MemoryTests.cs`: ++[InlineData(typeof(DatePicker))] public async Task HandlerDoesNotLeak(Type type) Solved the problem by fixing two places: * `MauiDatePicker` now uses a `UIDatePickerProxy` type, for iOS * `DatePickerHandler.MacCatalyst.cs` now uses a `UIDatePickerProxy` type, for MacCatalyst. Other changes: * Skip test on Android API 23 This is working for me locally on an API 23 emulator -- so I don't think it is really leaking. We skipped API 23 in another place: https://github.com/dotnet/maui/blob/9fcccd57b5a3d664e4788b3c7fc3edc10010beaf/src/Controls/tests/DeviceTests/Elements/NavigationPage/NavigationPageTests.cs#L302-L303 We are more interested in iOS on this PR anyway. * [build] Bump XCode to 14.31 (#16374) * Add doc comments for common types used in templates, maps, webview (#16552) * Add doc comments for common types used in templates, maps, webview * Enable WarnigsAsErrors for inline docs on Maps I went through every type/method/etc. used in the default MAUI app template and ensured there are doc for all of them. I also added a few miscellaneous docs for WebView types and Map (many were copied from Xamarin.Forms docs). --------- Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com> * Update CODEOWNERS (#16682) * Fix the case where silent was requested (#16676) * Use the correct WASDK property (#16683) * Re-land "[Windows] fixing window glitches while moving or resizing" (#16637) Initially merged in #14861 but there was a few test failures due to 83398c3 so it was reverted in #16541 * Update dependencies from https://github.com/xamarin/xamarin-macios build 20230815.5 Microsoft.tvOS.Sdk From Version 16.4.8694-net8-p7 -> To Version 16.4.8751-net8-rc1 * Update dependencies from https://github.com/xamarin/xamarin-macios build 20230815.5 Microsoft.MacCatalyst.Sdk From Version 16.4.8694-net8-p7 -> To Version 16.4.8751-net8-rc1 * Update dependencies from https://github.com/xamarin/xamarin-macios build 20230815.5 Microsoft.macOS.Sdk From Version 13.3.8694-net8-p7 -> To Version 13.3.8751-net8-rc1 * Update dependencies from https://github.com/xamarin/xamarin-macios build 20230815.5 Microsoft.iOS.Sdk From Version 16.4.8694-net8-p7 -> To Version 16.4.8751-net8-rc1 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Scott Banning <scoban@microsoft.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Juan Diego Herrera <juherrera@microsoft.com> Co-authored-by: Matthew Leibowitz <mattleibow@live.com> Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com> Co-authored-by: Rachel Kang <rachelkang@microsoft.com> Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com> Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Mausam Shrestha <46900712+mausam-shrestha@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shane Neuville <shneuvil@microsoft.com> Co-authored-by: Stephane Delcroix (HE/HIM) (from Dev Box) <stdelc@microsoft.com> Co-authored-by: Tim Miller <drasticactions@users.noreply.github.com> Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> Co-authored-by: TJ Lambert <50846373+tj-devel709@users.noreply.github.com> Co-authored-by: E.Z. Hart <hartez@users.noreply.github.com> Co-authored-by: Javier Suárez <6755973+jsuarezruiz@users.noreply.github.com> Co-authored-by: scoban <sbanni@users.noreply.github.com> Co-authored-by: Eilon Lipton <Eilon@users.noreply.github.com>
Description of Change
Android Timer can add callbacks to itself inside the Tick handler, resulting in an exponential explosion of Tick handlers. This adds a test for that situation and fixes it for Android.
Issues Fixed
Fixes #10257