App Doesn't Crash While Debugging, but Does When Running Normally
Asked Answered
S

1

5

System Information

  • Windows 10 Technical Preview (build 9926)
  • Visual Studio Community 2013

    Attempting to debug on:
  • [AT&T] Lumia 635 (Windows 10 Technical Preview for phones build 9941 w/ Lumia Cyan)
  • [AT&T] Lumia 1520 (Windows Phone 8.1 with Lumia Denim and PfD)
  • [Unlocked] BLU Win Jr (Windows Phone 8.1 with PfD)
  • [Verizon] Lumia Icon (Windows Phone 8.1 with Lumia Denim and PfD)

I trying to get location services working in my app. Previously, I had Visual Studio throw the error. It was an ArgumentException with the message "Use of undefined keyword value 1 for event TaskScheduled in async". Googling didn't turn up any solutions.

Here is the code:

Geolocator Locator = new Geolocator();
Geoposition Position = await Locator.GetGeopositionAsync();
Geocoordinate Coordinate = Position.Coordinate;

When I could get the error to be thrown, the exception was thrown on the 2nd or 3rd line in the sample above. I simplified the original code to try and fix it, but this is the original:

Geolocator Locator = new Geolocator();
Geocoordinate Coordinate = (await Locator.GetGeopositionAsync()).Position.Coordinate;

The entire app works when debugging, but crashes almost instantaneously otherwise.

This is a Windows 8.1 Universal project, focusing on the phone project.

Thanks in advance


EDIT: As requested, here is the full method:

private static bool CheckConnection()
{
    ConnectionProfile connections = NetworkInformation.GetInternetConnectionProfile();
    bool internet = connections != null && connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
    return internet;
}
public static async Task<double> GetTemperature(bool Force)
{
    if (CheckConnection() || Force)
    {
        Geolocator Locator = new Geolocator();
        await Task.Yield(); //Error occurs here
        Geoposition Position = await Locator.GetGeopositionAsync();
        Geocoordinate Coordinate = Position.Coordinate;
        HttpClient Client = new HttpClient();
        double Temperature;
        Uri u = new Uri(string.Format("http://api.worldweatheronline.com/free/v1/weather.ashx?q={0},{1}&format=xml&num_of_days=1&date=today&cc=yes&key={2}",
                                      Coordinate.Point.Position.Latitude,
                                      Coordinate.Point.Position.Longitude,
                                      "API KEY"),
                                      UriKind.Absolute);
        string Raw = await Client.GetStringAsync(u);
        XElement main = XElement.Parse(Raw), current_condition, temp_c;
        current_condition = main.Element("current_condition");
        temp_c = current_condition.Element("temp_C");
        Temperature = Convert.ToDouble(temp_c.Value);
        switch (Memory.TempUnit)
        {
            case 0:
                Temperature = Convertions.Temperature.CelsiusToFahrenheit(Temperature);
                break;
            case 2:
                Temperature = Convertions.Temperature.CelsiusToKelvin(Temperature);
                break;
        }
        return Temperature;
    }
    else
    {
        throw new InvalidOperationException("Cannot connect to the weather server.");
    }
}

EDIT 2: I've asked for help on Twitter, and received a reply asking for a repro project. I recreated the major portion of the original app, but I could not get the error. However, errors may occur for you so here's the project.


EDIT 3: If it helps at all, here are the exception details:

System.ArgumentException occurred
  _HResult=-2147024809
  _message=Use of undefined keyword value 1 for event TaskScheduled.
  HResult=-2147024809
  IsTransient=false
  Message=Use of undefined keyword value 1 for event TaskScheduled.
  Source=mscorlib
  StackTrace:
       at System.Diagnostics.Tracing.ManifestBuilder.GetKeywords(UInt64 keywords, String eventName)
  InnerException: 
Sensuous answered 2/2, 2015 at 0:2 Comment(8)
You're not alone, check this and this. As a workaround, see if this helps: Geoposition Position = await Task.Run(() => Locator.GetGeopositionAsync());Stibine
@Noseratio I've tried everything I could in the two threads you linked. Also, I tried the workaround you gave. It still works flawlessly while debugging, but it still crashes while not debugging. Thanks for your replySensuous
Apparently, it's a WP/WRT bug, I'd report it at connect.microsoft.com. BTW, try also this: await Task.Yeild(); Geocoordinate Coordinate = (await Locator.GetGeopositionAsync()).Position.Coordinate; Does it crash after Task.Yeild() or after await Locator.GetGeopositionAsync()?Stibine
BTW, I appreciate your're dealing with this complex stuff at your age, well done :)Stibine
@Noseratio I set it up with MessageDialogs that popup after Task.Yield() and await Locator.GetGeopositionAsync(). My guess is that it crashes at Task.Yield() because none of the dialogs popup. Again, it only does this while not debugging. Thanks btw, haha :PSensuous
What is the home method for this code, is it an event handler? Could you edit your q. and show it?Stibine
Greg, your code is missing await before Task.Yield(), see if it makes any difference. Also what I meant is, what's the root method of the call chain leading to GetTemperature. Is it an async void UI event handler, or something like OnLaunched? Also, what do you see if you add Debug.WriteLine(new { SynchronizationContext.Current }) to the beginning of GetTemperature?Stibine
@Noseratio Oops, I had await in my code, but forgot to add it in the snippet. The stack starts from protected override async void OnNavigatedTo(NavigationEventArgs e), to a method that eventually calls GetTemperature(false) (awaited). As for Debug.WriteLine(new { SynchronizationContext.Current }), it prints { Current = System.Threading.WinRTSynchronizationContext }.Sensuous
S
1

Having checked this and this, I believe this is a bug in .NET async/await infrastructure for WinRT. I couldn't repro it, but I encourage you to try the following workaround, see if it works for you.

  • Factor out all asynchronous awaitable calls from OnNavigatedTo into a separate async Task method, e.g. ContinueAsync:

    async Task ContinueAsync()
    {
        Geolocator Locator = new Geolocator();
        Geoposition Position = await Locator.GetGeopositionAsync();
        Geocoordinate Coordinate = Position.Coordinate; 
    
        // ...
    
        var messageDialog = new Windows.UI.Popups.MessageDialog("Hello");
        await messageDialog.ShowAsync();
    
        // ...
    }
    
  • Remove async modifier from OnNavigatedTo and call ContinueAsync from OnNavigatedTo like this:

    var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.StartNew(
        () => ContinueAsync(), 
        CancellationToken.None, TaskCreationOptions.None, scheduler).
        Unwrap().
        ContinueWith(t => 
        {
            try
            {
                t.GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                throw; // re-throw or handle somehow
            }
        }, 
        CancellationToken.None,            
        TaskContinuationOptions.NotOnRanToCompletion, 
        scheduler);
    

Let us know if it helps :)


Updated, apparently, the bug is somewhere in the TPL logging provider, TplEtwProvider. You can see it's getting created if you add the below code. So far, I couldn't find a way to disable this event source (either directly or via Reflection):

internal class MyEventListener : EventListener
{
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        base.OnEventSourceCreated(eventSource);
        if (eventSource.Name == "System.Threading.Tasks.TplEventSource")
        {
            var enabled = eventSource.IsEnabled();

            // trying to disable - unsupported command :(
            System.Diagnostics.Tracing.EventSource.SendCommand(
                eventSource, EventCommand.Disable, new System.Collections.Generic.Dictionary<string, string>());
        }
    }
}

// ...
public sealed partial class App : Application
{
    static MyEventListener listener = new MyEventListener();
}
Stibine answered 3/2, 2015 at 0:19 Comment(9)
Thanks for your help, but I still can't get this to work. I have no idea why this is happening and I see that many other people are getting this too.Sensuous
Hi Greg - I think this is a bug. I'll file it and update you when I know more. I can't promise how fast a fix will come. Please post a link to a reproduction project on OneDrive and I'll have something to forward to the PG.Flyblown
@MattSmall, pls see my update about TplEtwProvider event source. Is it possible to disable it altogether for a Windows Phone/Windows Store app?Stibine
@Noseratio I've added the code you've given and added a few Debug.WriteLines to see output: pastebin.com/7JxbvyeCSensuous
@GregWhatley, this pastbin seems to be private, I can't see it.Stibine
@GregWhatley, you may want to keep an eye on this: https://mcmap.net/q/664676/-how-to-disable-task-parallel-library-39-s-etw-eventsource-in-a-universal-appStibine
@Noseratio Sorry, try it nowSensuous
@GregWhatley, yeah, that's the expected output (for "Invalid command value", at least). So far, we haven't figured it out how to disable that EventSource.Stibine
I'll check this out but won't update until week after next as I am going to be out of the office.Flyblown

© 2022 - 2024 — McMap. All rights reserved.