{"KeyNotFoundException"}

Apr 19, 2011 at 7:13 AM
Edited Apr 19, 2011 at 7:33 AM

Hi,

I update some 100 records, while saving  my app is tombstoned and when I come back, i get this exception

in Log function at this line

 Action action = () => _loggers[key1](level, message, exception);

(A first chance exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in mscorlib.dll)

what could be going wrong..?

while that loop is updating records, i tombstoned returned back to app 2 times..

-UK

Coordinator
Apr 19, 2011 at 8:28 PM

I don't know what your implementation looks like, but it sounds like you are not calling flush in the tombstone event. That is required to synchronize the keys. If you have a common scenario of tombstone happening during save, you should probably look at batching saves and flushing manually after so many commits to minimize disruption.

Apr 20, 2011 at 1:16 PM
Edited Apr 20, 2011 at 1:17 PM

Hi,

I am really into mess,

I m writing IM application, I download all the messages in a thread and store in database...

chat page/view is webbrowser control. I use javascript to add messages to view.So Onload event of browser control, I read all messages between me and other user.

Also as I read all these msgs I need to update msg as read (set to True) as i display some icons to indicates these msg r read.

when the page comes up onload event is fired, I read the messages from the database and this loop never stops even during tombstone...

once this loop comes out only Deactivated event is raised.. so in between if i navigate away (onNavigatedFrom, onNavigatedTo events called for the page) , that loop is still running.. and finally deactived and Onnavigaged events called and I get the above exception of KeyNotFound

I am not sure, why the loop is not getting terminated when app goes to tombstoned state.

Below is how I got the trace

 

Conversation  - LoadMessages
In LoadFrom Datbase
 
.1
.2
.3
.4
.5
.6
.7
.8
.9
.10
-........(it doesn't stop)

Conversation - OnNavigatedFrom
Application_Deactivated
Application_Activated
Getting IsolatedStorage for current Application
Checking channel data
Channel data not found
 
Trying to open the channel
A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.Phone.dll
The thread '<No Name>' (0x14890ed2) has exited with code 0 (0x0).
20/4/2011 20:42:41::Sterling::Information::Sterling is registering database myapp.myappDatabases.myappDatabase
Conversation  - OnNavigatedTo
 
Conversation - OnNavigatedFrom
Conversation  - OnNavigatedTo
 
Conversation - OnNavigatedFrom
Conversation  - OnNavigatedTo
 A first chance exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in mscorlib.dll
The thread '<No Name>' (0x142f0e7e) has exited with code 0 (0x0).
The thread '<No Name>' (0x14790b2e) has exited with code 0 (0x0).

Below is the Code :

 

private void webBrowser_ScriptNotify(object sender, NotifyEventArgs e)
        {
            if (e.Value == "onload")
            {
                LoadMessages();
            }
}

  void LoadMessages()
        {
           
            this.progressBar.Visibility = System.Windows.Visibility.Visible;
            Thread oThreadReadMsgs = new Thread((this.LoadFromDatbase));
            oThreadReadMsgs.Start();
 
        }

 

 public void LoadFromDatbase()
        {
            IEnumerable items = null;
            readMessageIDs = new List<long>();
            int nRecords = 0;

            Utils.Trace("In LoadFrom Datbase");
           
            if (App.SterDatabase == null) return;

            var range = from k in App.SterDatabase.Query<DatabaseItems, long>()
                        where k.LazyValue.Value.receiverID == recipientID || k.LazyValue.Value.senderID == recipientID
                        orderby k.Key
                        select k.LazyValue.Value;

            

            this.Dispatcher.BeginInvoke(delegate()
            {
                foreach (var item in range)
                {
                    DatabaseItems delmsg = item;
                    nRecords++;

                    if (delmsg.incoming == true && delmsg.isMsgRead == false)
                    {
                        delmsg.isMsgRead = true;

                        try
                        {
                            if (App.SterDatabase == null) return;
                            App.SterDatabase.Save(delmsg);
                        }
                        catch (Exception exp)
                        {

                        }

                        readMessageIDs.Add(delmsg.msgID);
                    }

                    AddMessageToConversation(delmsg); //Add msg to UI-BrowserControl
             

                     Utils.Trace("." + nRecords.ToString());
                }

              

                this.progressBar.Visibility = System.Windows.Visibility.Collapsed;
            });

        
            //Update Read Status to Server
            updateMessageReadStatus();
        }



 

Coordinator
Apr 20, 2011 at 2:54 PM

Again, not enough context for me to understand what is going on. If you are comfortable sharing the project with me, you can use the contact form and I'll queue it to take a look at it.

One thing that jumps out is the use of the lazy value to inspect the sender and receiver ids. That will be very expensive and slow if you have a lot of records as that will deserialize everything just to make the check. Is there any reason you don't have those ids specified as indexes so you can query them faster and only lazy load the filtered items?

Apr 21, 2011 at 4:54 AM
Edited Apr 21, 2011 at 4:55 AM

Hi Jeremy

Yes I changed it now,

     CreateTableDefinition<DatabaseItems, long>(dbRecord => dbRecord.msgID)
                .WithIndex<DatabaseItems, long, long, long>("IndexData", t => Tuple.Create(t.senderID, t.receiverID)),

 

and my query as

       var range = from key in App.SterDatabase.Query<DatabaseItems, long, long, long>("IndexData")
                        where key.Index.Item1 == recipientID || key.Index.Item2 == recipientID
                        orderby key.Key
                        select key.LazyValue.Value;

My project is quite big, I will try to upload.

I am downloading and updating records in back ground thread and also reading messages as above , when tombstones,  not sure what exactly happening it leads to crash.

Apr 21, 2011 at 11:59 AM

Is that above fine? and i hv a doubt,  if i access database in multiple threads doing writes and reads will it create problem?

another observation is that: if i don't read the msgs as below, I don't get the exception (KeyNotFoundException)

var range = from key in App.SterDatabase.Query<DatabaseItems, long, long, long>("IndexData")
                        where key.Index.Item1 == recipientID || key.Index.Item2 == recipientID
                        orderby key.Key
                        select key.LazyValue.Value;

 

Coordinator
Apr 21, 2011 at 6:25 PM

Not quite sure I understand - so it's not a problem now or you still have an issue?