Unable to read beyond the end of the stream.

Aug 5, 2011 at 9:41 PM
Edited Aug 11, 2011 at 5:01 PM

I seem to be randomly getting the below error.  I have a feeling that it has something to do with running a Query while the Flush() method is still processing???  I'm using the Pivot control in my WP7 project the first pivot page is downloading and saving and the second pivot page is running a query.

8/7 Update.   It looks like the Flush isn't the problem, I commented it out and can still reproduce the error.   What I'm noticing is the following query will run twice.  The first time there is nothing in the DB and no error.   The second time the query runs after the DB has been populated if "BaseDate" has not changed  I will get the below exception; if I use a different BaseDate for the 2nd query everything is OK.

Flights = (from f in App.Database.Query<FlightEvent, Guid>()
                       where f.LazyValue.Value.Schedule.BASE_DATE == BaseDate
                       orderby f.LazyValue.Value.LAUNCH_DATE
                       select f.LazyValue.Value).ToList();

 8/11 Update.  I was starting more than 10 httpwebrequests at a time and in the callback for each request i was Saving and Flushing.  After changing my code to only do one request at a time the error has gone away.  So maybe the issue was multiple Flush's being called at the same time???

 

Unable to read beyond the end of the stream.
   at System.IO.__Error.EndOfFile()
   at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
   at System.IO.BinaryReader.ReadInt32()
   at Wintellect.Sterling.Serialization.SerializationHelper._Deserialize(BinaryReader br, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper.Load(Type type, Object key, BinaryReader br, CycleCache cache)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Load(Type type, Object key, CycleCache cache)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Load(Type type, Object key)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Load[T,TKey](Guid key)
   at Wintellect.Sterling.Keys.TableKey`2.<.ctor>b__0()
   at System.Lazy`1.get_Value()
   at ScheduleViewer.ViewModels.FlightsViewModel.<LoadData>b__0(TableKey`2 f)
   at System.Linq.Enumerable.<WhereIterator>d__0`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
   at System.Linq.Enumerable.<SelectIterator>d__d`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at ScheduleViewer.ViewModels.FlightsViewModel.LoadData()
   at ScheduleViewer.ViewModels.FlightsViewModel.set_BaseDate(DateTime value)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.InternalSetValue(PropertyInfo thisProperty, Object obj, Object value, Object[] index, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at System.Windows.CLRPropertyListener.set_Value(Object value)
   at System.Windows.PropertyAccessPathStep.set_Value(Object value)
   at System.Windows.PropertyPathListener.set_LeafValue(Object value)
   at System.Windows.Data.BindingExpression.UpdateValue()
   at System.Windows.Data.BindingExpression.UpdateValueIfNecessary()
   at System.Windows.Data.BindingExpression.TargetPropertyChanged(DependencyObject sender, DependencyProperty dp)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyProperty dp)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyProperty dp)
   at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object oldValue, Object newValue)
   at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at Microsoft.Phone.Controls.DateTimePickerBase.set_Value(Nullable`1 value)
   at Microsoft.Phone.Controls.DateTimePickerBase.ClosePickerPage()
   at Microsoft.Phone.Controls.DateTimePickerBase.HandleFrameNavigated(Object sender, NavigationEventArgs e)
   at System.Windows.Navigation.NavigationService.RaiseNavigated(Object content, Uri uri, NavigationMode mode, Boolean isNavigationInitiator, PhoneApplicationPage existingContentPage, PhoneApplicationPage newContentPage)
   at System.Windows.Navigation.NavigationService.CompleteNavigation(DependencyObject content, NavigationMode mode)
   at System.Windows.Navigation.NavigationService.<>c__DisplayClass7.<NavigateCore_ContinueNavigation>b__4()
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

Oct 10, 2011 at 12:44 PM

Hi,

 

I seem to get the same symptoms. Occasionally our users get a broken database, which results in the same EndOfStreamException as above when trying to load from the database.

From what our users report, it could be an tombstoning issue. I do flush and dispose sterling in the deactivated event and I do flush after saving a batch of data.

 

I've looked through the code of sterling a bit. I've yet to fully understand it, but it seems to me that the problem could be following:

When saving an large object, in BaseDatabaseInstance.Save the key is stored in the keys list (and saved in keys.dat due to OnDeactivated-flush). (BaseDatabaseInstance:535 i guess)

WP7 aborts everything before the app gets a chance to create the file and write the deserialized data. (BaseDatabaseInstance:560)

Resulting in a reference in the keys.dat to an empty/non-existant file.

Which in turn results in the EndOfStreamException.

 

Jeremy, could you confirm wether or not this scenario could be possible?

Coordinator
Oct 11, 2011 at 3:57 PM

This could certainly happen. One of the things we were looking at for vNext is using a more consolidated file approach which should cut down on the possibility of these issues but if the flush/abort cuts the application off before the file can be serialized this may happen. One resolution being considered is to always write a new copy of the files and then rename after write to avoid corruption of the database.

Oct 12, 2011 at 10:43 AM

Thanks for the clarification.

I tried to implement a hotfix where the file would be written first and only after that it's finished, the key is being added to KeyCollection.

I.e.

1. in BaseDatabaseInstance first reserve key by getting NextKey++ from KeyCollection

2. write file

3. commit key by calling _keyMap.Add

My implementation was buggy and just didn't work. But would that approach basically be a viable solution for a hotfix?

Coordinator
Oct 12, 2011 at 12:10 PM

Yes, that's close to what I'm looking at for a fix - basically write the key file with the new key, then once it is written, rename it the actual key file and refresh so it is always intact.

Jan 4, 2012 at 2:16 PM

Hi, I think I have a similar issue occurring in my app, have been any updates on this issue?