Skip to content

Exception on Start() #31

Open
Open

Description

@ncosentino

Just wanted to give this library a whirl. Seems pretty easy to use, which was a big bonus for me. I had things working with these lines for my setup:

AutoMeasurement.Instance = new WinFormAutoMeasurement();
AutoMeasurement.Instance.Start(new MeasurementConfiguration("UA-60679857-1", Application.ProductName, Application.ProductVersion), "Debug");

And then on a screen I'd call

AutoMeasurement.Client.TrackScreenView("My Screen");

Now on startup (specifically, only if I include the .Start() line, I get the following exception:

There was an error deserializing the object of type System.Collections.Generic.List1[[System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]. The data at the root level is invalid. Line 1, position 1. at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader) at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream stream) at CSharpAnalytics.Serializers.AppDataContractSerializer.<Restore>d__01.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at CSharpAnalytics.WinFormAutoMeasurement.<Load>d__01.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CSharpAnalytics.BaseAutoMeasurement.d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at CSharpAnalytics.BaseAutoMeasurement.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__1(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
The data at the root level is invalid. Line 1, position 1.
at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
at System.Xml.XmlUTF8TextReader.Read()
at System.Xml.XmlBaseReader.IsStartElement()
at System.Xml.XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
at System.Runtime.Serialization.XmlReaderDelegator.IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)
at System.Runtime.Serialization.XmlObjectSerializer.IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns)
at System.Runtime.Serialization.DataContractSerializer.InternalIsStartObject(XmlReaderDelegator reader)
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)

I feel like it's trying to restore some state or something, but I've blown away my bin directory and I've checked source control to ensure I have no other changes. It just stopped working out of (seemingly) nowhere and now I can't really do all that much.

Definite props for putting something together that's so easy to use though.

Activity

  1. ncosentino commented on Mar 14, 2015

    @ncosentino
    Author

    Just to update... I pulled the source instead of using the Nuget package (I figured I'd try to investigate myself instead of being entirely useless). My application is trying to restore state from two files:

    C:\Users\XXXX\AppData\Roaming\XXXXXXXXXXXXX\CSharpAnalytics-MeasurementSession
    C:\Users\XXXXX\AppData\Roaming\XXXXXXXXXXXXXXXX\CSharpAnalytics-MeasurementQueue

    The first file looked well formed. The second file was entirely NUL characters when I opened it in notepad++.. When I manually blew away the contents of the second file, things are back to working.

    I can continue to play around now, but I'd still like to keep this open until there's a resolution for how this might be handled in a real client environment. Unfortunately, I don't know what caused it in the first place.

    Let me know if you need any more information from me.

  2. damieng commented on Mar 14, 2015

    @damieng
    Contributor

    That is weird.

    In a non-debug scenario it generally just ignores the badly read file and
    overwrites it but I don't understand how you would have ended up with a bad
    file in the first place...

    [)amien

    On Fri, Mar 13, 2015 at 9:59 PM, Nick Cosentino notifications@github.com
    wrote:

    Just to update... I pulled the source instead of using the Nuget package
    (I figured I'd try to investigate myself instead of being entirely
    useless). My application is trying to restore state from two files:

    C:\Users\XXXX\AppData\Roaming\XXXXXXXXXXXXX\CSharpAnalytics-MeasurementSession

    C:\Users\XXXXX\AppData\Roaming\XXXXXXXXXXXXXXXX\CSharpAnalytics-MeasurementQueue

    The first file looked well formed. The second file was entirely NUL
    characters when I opened it in notepad++.. When I manually blew away the
    contents of the second file, things are back to working.

    I can continue to play around now, but I'd still like to keep this open
    until there's a resolution for how this might be handled in a real client
    environment. Unfortunately, I don't know what caused it in the first place.

    Let me know if you need any more information from me.

    —
    Reply to this email directly or view it on GitHub
    #31 (comment)
    .

  3. ncosentino commented on Mar 14, 2015

    @ncosentino
    Author

    (First time having my eyes on the code, so forgive me if I'm being obvious or oblivious haha)

    This signature in the base class:

    public static async Task<T> Restore<T>(string filename = null, bool deleteBadData = false)
    

    Looks like it's always left as the default false. I'm using the WinForms implementation, so:

    protected override async Task<T> Load<T>(string name)
    {
        return await AppDataContractSerializer.Restore<T>(name);
    }
    

    So it seems like once I get into a corrupt state (still haven't repro'd) I'm kind of stuck like that. Even aside from being stuck like that, I imagine the first time it happens would still result in an app crash, require an app restart, and then things might be okay?

  4. damieng commented on Mar 14, 2015

    @damieng
    Contributor

    Thanks for that. I haven't use the WinForms/WPF implementations myself
    they were user contributed but I'll fix that this weekend.

    Thanks for the heads up!

    [)amien

    On Fri, Mar 13, 2015 at 10:17 PM, Nick Cosentino notifications@github.com
    wrote:

    (First time having my eyes on the code, so forgive me if I'm being obvious
    or oblivious haha)

    This signature in the base class:

    public static async Task Restore(string filename = null, bool deleteBadData = false)

    Looks like it's always left as the default false. I'm using the WinForms
    implementation, so:

    protected override async Task Load(string name)
    {
    return await AppDataContractSerializer.Restore(name);
    }

    So it seems like once I get into a corrupt state (still haven't repro'd)
    I'm kind of stuck like that. Even aside from being stuck like that, I
    imagine the first time it happens would still result in an app crash,
    require an app restart, and then things might be okay?

    —
    Reply to this email directly or view it on GitHub
    #31 (comment)
    .

  5. ncosentino commented on Mar 14, 2015

    @ncosentino
    Author

    Cool! Thanks for being so responsive. That's greatly appreciated!

  6. ncosentino commented on Mar 14, 2015

    @ncosentino
    Author

    Figured I'd mention this in the same spot since you said you'd be looking at the WinForm/WPF implementations... It looks like between application restarts as long as I have one of those session files, I can't seem to get metrics sent off. As soon as I delete those two files, things go back to normal.

    I tried poking around in the WinForms code, and got back to the AppDataContractSerializer. Within here, the line that actually performs the return is never hit (and the exception handlers around this code don't seem to get hit either).

    using (var memoryStream = new MemoryStream())
    {
        await inputStream.CopyToAsync(memoryStream);
        await inputStream.FlushAsync();
        memoryStream.Seek(0, SeekOrigin.Begin);
    
        return (T)serializer.ReadObject(memoryStream);
    }
    

    It's as if the files will just hang on being loaded if they exist, unless I'm misunderstanding how the async behaviour is working. Again, not sure if it's related at all, but I didn't want to tack on another issue if you think this type of thing is related.

  7. interwanderer commented on May 15, 2015

    @interwanderer

    Hi,

    I had the same problem, not sure why, maybe because I've been debugging... My file (CSharpAnalytics-MeasurementQueue ) look like the following:

    <ArrayOfanyURI xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/><ArrayOfanyURI xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
    

    Just put the following in a Try Catch :

                try
                {
                    await StartRequesterAsync();
                }
                catch (Exception ex)
                {
                    //todo: put something in here to log
                }
    

    inside BaseAutoMeasurement.cs

    And the file gets recreated. Next time up, metrics are recorded again.

    Hope this helps !

    PS. @damieng Thank you for sharing your awsome solution.

  8. JimiC commented on Oct 22, 2015

    @JimiC

    I managed to reproduce this issue and the cause is that the CSharpAnalytics-MeasurementQueue file is shared across all instances if you ran multiple instances of an app using the library, ending up writing multiple serialized objects in the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions