Xamarin-macios: PresentViewControllerAsync task never finishes if failed

Created on 21 Jan 2018  ·  17Comments  ·  Source: xamarin/xamarin-macios

Steps to Reproduce

On iOS:

  1. Schedule presenting a modal view controller for a few seconds ahead. Present with the method await PresentViewControllerAsync
  2. Meanwhile, present another modal view controller and keep it visible
  3. When the second await PresentViewControllerAsync occurs, you will get a log Warning: Attempt to present <MyViewController: 0x7fc89dd41090> on <MyNavigationController: 0x7fc89f0caa00> which is already presenting, as expected
  4. But the problem is, it does not throw error and the PresentViewControllerAsync task never finishes, so any following code will never be executed and it also cannot be catched in a try/catch block
  5. If you use the sync alternative, PresentViewController, the callback will not be called, but that is something that you can expect if the presenting fails. But you don't expect a neverending task.

EXAMPLE: It is an unexpected and serious issue e.g. when you call the await PresentViewControllerAsync inside a SemaphoreSlim. You expect to catch all errors between WaitAsync() and Release() in a try catch block, making sure the semaphore will never get stuck, but this one cannot be catched and Release() will never be hit, hence the semaphore gets stuck.

Expected Behavior

The PresentViewControllerAsync should throw an error.

Actual Behavior

The PresentViewControllerAsync task silently fails and never finishes.

Environment

Microsoft Visual Studio Community 2017 
Version 15.5.2
VisualStudio.15.Release/15.5.2+27130.2010
Microsoft .NET Framework
Version 4.7.02556

Installed Version: Community

Visual Basic 2017   00369-60000-00001-AA614
Microsoft Visual Basic 2017

Visual C# 2017   00369-60000-00001-AA614
Microsoft Visual C# 2017

Visual F# 4.1   00369-60000-00001-AA614
Microsoft Visual F# 4.1

Application Insights Tools for Visual Studio Package   8.10.01106.1
Application Insights Tools for Visual Studio

ASP.NET and Web Tools 2017   15.0.31125.0
ASP.NET and Web Tools 2017

ASP.NET Core Razor Language Services   1.0
Provides languages services for ASP.NET Core Razor.

ASP.NET Web Frameworks and Tools 2017   5.2.51007.0
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   15.0.31106.0
Azure App Service Tools v3.0.0

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

JavaScript Language Service   2.0
JavaScript Language Service

JavaScript Project System   2.0
JavaScript Project System

Merq   1.1.17-rc (cba4571)
Command Bus, Event Stream and Async Manager for Visual Studio extensions.

Microsoft Azure Tools   2.9
Microsoft Azure Tools for Microsoft Visual Studio 2017 - v2.9.51120.3

Microsoft Continuous Delivery Tools for Visual Studio   0.3
Simplifying the configuration of continuous build integration and continuous build delivery from within the Visual Studio IDE.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual Studio Tools for Containers   1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Mono Debugging for Visual Studio   4.8.4-pre (3fe64e3)
Support for debugging Mono processes with Visual Studio.

Node.js Tools   1.4.11025.7
Adds support for developing and debugging Node.js apps in Visual Studio

NuGet Package Manager   4.5.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

SQL Server Data Tools   15.1.61710.120
Microsoft SQL Server Data Tools

TypeScript Tools   15.5.11025.1
TypeScript Tools for Microsoft Visual Studio

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

Xamarin   4.8.0.753 (6575bd113)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   4.8.188 (c5813fa34)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin.Android SDK   8.1.0.25 (HEAD/d8c6e504f)
Xamarin.Android Reference Assemblies and MSBuild support.

Xamarin.iOS and Xamarin.Mac SDK   11.6.1.2 (6857dfc)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
iOS support

All 17 comments

Hi, could you please provide a quick test case showing the issue? This way we'd have the exact code you used to trigger the issue and will be able to investigate your project options.

Please also include your full build logs.

To get full build logs just set the log verbosity to diagnostic at the following locations:

  • On Visual Studio for Mac: Preferences > Projects > Build
  • On Visual Studio for Windows: Tools > Options > Projects and Solutions > Build and Run

On Visual Studio Windows you also want to add -v -v -v -v to the mtouch additional arguments by right-clicking the project in the solution explorer and selecting Properties.
Note: this is done automatically on Visual Studio for Mac when the log verbosity is set to diagnostic.

Hi Vincent, thanks for the reply. Unfortunately, I currently don't have much time to cooperate on the bug, I just reported it, hoping that someone from xamarin staff will try to resolve it. I believe that I provided clear and simple steps to reproduce it and I believe that it is that kind of bug that is happening in every situation, in every environment.

One quick example when it should happen, hope it helps (but not tested, just an example):

await PresentViewControllerAsync(controllerA);
await Task.Delay(5000);
try
{
var thisTaskNeverFinishes = PresentViewControllerAsync(controllerB); //this fails because already presenting
await thisTaskNeverFinishes;
}
catch (Exception e)
{
var error = "is not thrown";
}
var thisIs = "never reached";

@VincentDondain I'll try to create a sample for this issues to confirm it.

@mandel-macaque have you had a chance to look into this?

Will update a sample ASAP.

Can you please confirm in the following code is what you are using:

AwaitSyncControllerExample.zip

@mandel-macaque I don't know if I am doing something wrong, but the app doesn't do anything, I see just a blank screen.

@rihadavid strange, should be good enough with running the app. Let me take a look and get some screenshots for you.

I have confirmed the issue with the attached project. Will set the milestone to take a look at it ASAP.

The blank screen has nothing to do with async being used. Even if you use a single alert, not *Async,, e.g. use something like:

            PresentViewController (firstAlertController, true, () => {
                Console.WriteLine (":-)");
            });

you'll still get that empty screen.

The hint comes from the application output, which shows:

2018-10-18 10:19:50.909220-0400 AwaitSyncControllerExample[68110:18859179] Warning: Attempt to present <UIAlertController: 0x7ff02588f200> on <ViewController: 0x7ff024430730> whose view is not in the window hierarchy!

and, effectively, the firstAlertController.VIew.Window is null.

Why ? when ViewDidLoad is executed iOS has not yet set up everything you need. Loading the view and having it ready to be used are different.

Solution: switch to use ViewDidAppear and things will work (well appear).

The 2nd alert will still block because the main/ui thread has not completed its work on the first one. Your await is not awaiting its dismissal, only that it returned.

@spouliot Sorry but I don't understand your conclusion, it seems to me that you are trying to explain why the sample project from @mandel-macaque wasn't doing anything, but it has nothing to do with the issue I reported. This report is not about some "empty screen" and also not about ViewDidLoad or ViewDidAppear methods. The sample code I provided can be run from whatever method and the never-ending issue will be present.
I think there is some misunderstanding, this issue should not be closed.

@spouliot ?

Please attach a self-contained test case we can build to reproduce and we'll have another look. Thanks!

As if it was some hard task to take the few lines of code I provided and put it in a sample project.. 🤦‍♂️
Here you go:
App5.zip

Please look at the code in ViewController.cs ViewDidAppear(), nothing else is relevant

Hello

Thank you for your report. we provide async methods as a convenience and we absolutely understand your concern, unfortunately due to the nature of the native API there is no way for us to hook up on the error state programmatically of this particular API and throw on such condition. In essence we still mimic the nature of the native API call, the PresentViewController's completion handler is never called, so no code is executed on either case after the error happens.

We consider this to be the expected behavior hence we won't reopen the issue. Thanks again for reporting it.

Ok, understood, thanks!

Was this page helpful?
0 / 5 - 0 ratings