Skip to content
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

Exception on Start() #31

Open
ncosentino opened this issue Mar 14, 2015 · 8 comments
Open

Exception on Start() #31

ncosentino opened this issue Mar 14, 2015 · 8 comments

Comments

@ncosentino
Copy link

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.

@ncosentino
Copy link
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.

@damieng
Copy link
Contributor

damieng commented Mar 14, 2015

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 [email protected]
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)
.

@ncosentino
Copy link
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?

@damieng
Copy link
Contributor

damieng commented Mar 14, 2015

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 [email protected]
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)
.

@ncosentino
Copy link
Author

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

@ncosentino
Copy link
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.

@interwanderer
Copy link

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.

@JimiC
Copy link

JimiC commented Oct 22, 2015

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.

JimiC added a commit to JimiC/CSharpAnalytics that referenced this issue Oct 22, 2015
…re running multiple instances cause various exceptions to be thrown.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants