In Access, always supposed that in Forms modules, as in other (class or regular) modules, objects and normal variables cease to exist when the code is exited, or in the case of Forms, when the form is closed. Is that correct ?
I am wondering because I built a form used to scan barcodes on orders, and it gets slower and slower during the day, until the user closes and reopens the DB, then everything is back to normal. Closing the form does not seem to be enough. I analysed my code, and I can't find much, so serching for the culprit...
I think ideally when objects go out of scope they will be destroyed and the memory they used will be released. However, since sometimes things don't go according to plan, I thought we're supposed to explicitly close and release any recordset objects we create in our code ... just to be safe.
Is this form being opened and closed many times during the session? I had a problem in Access 97 where a similar problem would occur. Hideing the form instead of closing it and then making it visible again solved the problem. However any form level variables had to be explicitly set to zero or zero length strings.
Related
This question is a little "meta" for SO, but there doesn't seem to be a better place to ask it...
According to Google, realtime collaborative objects are never deleted from the model. So it makes sense to pool objects where possible, rather than not-really-delete them and subsequently create new ones, thus preventing an unnecessary increase in file-size and overhead.
And here's the problem: in an "undo" scenario, this would mean pulling a deleted object out of the trash pool. But "undo" only applies to operations by the local user, and I can't see how the realtime engine could cope if that "deleted" object had already been claimed by a different user.
My question is, am I missing something or wrong-thinking, and/or is there an alternative to a per-user pool?
(It also occurs to me that as a feature, the API could handle pooling deleted objects, automatically minimizing file-bloat.)
I think you have to be very careful about reusing objects in the way you describe. Its really hard to get right. Are you actually running into size issues? In general as long as you don't constantly create and throw out objects, it shouldn't be a big deal.
You can delete the contents of the collab object when its not being used to free up space. That should generally be enough.
(Note, yes, the API could theoretically handle this object cleanup automatically. It turns out to be a really tricky problem to get right, do to features like undo. It might show up as a future feature if it becomes a real issue for people.)
Adding to Cheryl's answer, the one thing that I see as particularly challenging (actually, impossible) is the pulling-an-object-from-the-pool stuff:
Let's say you have a pool of objects, which (currently) contains a single object O1.
When a client needs a new object it will first check the pool. if the pool is not empty it will pull an object from there (the O1 object) and use it, right?
Now, consider the scenario where two clients (a.k.a, editors/collaborators) need a new object at the same time. Each of these clients will run the logic described in the previous paragraph. That is: both clients will check whether the pool is empty and both clients will pull O1 off of the pull.
So, the loosing client will "think" for some time that it succeeded. it will grab an object from the pool and will do some things with it. later on it will receive an event (E) that tells it that the object was actually pulled by another client. At this point the "loosing" client will need to create another object and re-apply whatever changes it did to the first object to this second object.
Given that you do not know if/when the (E) event is going to fire it actually means that every client needs to be prepared to replace every collaborative object it uses with a new one. This seems quite difficult. Making it more difficult is the fact that you cannot do model changes from event handlers (as this will trump the redo/undo stack). So the actual reaction to the (E) event need to be carried out outside of the (E) event handler. Thus, in the time between the receiving of the (E) event and the fix to the model, your UI layer will not be able to use the model.
I am suffering from a memory leap within my WP8 app.
I have investigated and narrowed the problem down though I would like some guidance on where to go next.
I do have a hunch that the Pivot and LongListSelector are the cause, described below.
Problem Description:
App browses across numerous pages (typically a few dozen).
Memory use is increasing by around 2-4MB per page and not being fully released.
After around 25 pages memory use has increased from 30MB to 90MB.
Existing Code:
I am already performing some cleanup on each page before navigating to the next.
I am also already calling NavigationService.RemoveBackEntry() to keep the Back Stack small.
Investigation:
I have used the Memory Profiler which reveals about 15MB of the growth is my own data that isn't being cleaned up.
The remaining 40-50MB is not included in the Heap Summary (i.e. the total only comes to about 15MB out of the observed 90MB).
I will work on the 15MB, but since it doesn't appear to be the most significant factor, I would like some guidance on sensible next steps.
Possible Cause:
I have another set of pages (again typically a few dozen pages when browsed) composed of very similar content.
These pages however do NOT show the same problem. Memory use remains low throughout.
Both sets of pages use similar cleanup code when navigating.
One key difference is the affected pages use a Pivot control, each of which has a 3 or 4 Pivot Items, a couple of which contain LongListSelectors.
The LongListSelectors are data bound to Generic Lists generated at run time. No images, only text. Not especially long lists, 20 or so items in each.
I have come across a couple of posts vaguely suggesting that this combination of controls is susceptible to memory leaks.
I commented the code that populates these controls, and sure enough, memory use now peaks at around 50-60MB.
It may be even lower if I remove the controls completely (I haven't tested that yet).
So, these controls are not the whole story, but clearly are a large part of the problem.
Question:
Is there a known issue with these controls (LongListSelector, Pivot)?
Should there be some code used to clean up these controls? I have tried setting the list ItemSource to an empty list, but this had no effect on the memory growth.
Is there any way to workaround it? (obviously changing the type of controls used is one option).
Thanks for reading.
After some investigation, I have found what looks like a problem with the LongListSelector recovering memory when it is cleaned up.
I have posted more details and a workaround here:
http://cbailiss.wordpress.com/2014/01/24/windows-phone-8-longlistselector-memory-leak/
I had a same problem. All I did just changed source List<>s to ObservableCollection<>s, and then on SelectedItem changing I clearing source collection which is not visible at the moment.
I really enjoy using Chrome's URL bar because it remembers commonly-visited sites and often suggests a good completion based on what I've typed and/or visited before. So, for example, I can type t in the URL bar and Chrome will automatically fill it in with twitter.com, or I can type maps and Chrome will fill in the .google.com. This gives me the convenience of data-driven domain name shortcuts without having to maintain an explicit list.
What I'm wondering, though, is how Chrome determines that an old shortcut should be replaced with a new one. For example, if I visit twitter.com often, then that becomes the completion when I type t. But if I then start visiting twilio.com often enough, then, after some time, Chrome will start to fill that in as the default completion for t. What I can't figure out is how or when that transition takes place. It also seems that there are (at least) two cases involved : one for domain names, and another for path strings, because if I visit a certain full URL often, and then want to get to the root of the same domain, I end up having to type the entire domain name out to get Chrome to ignore the full-URL completion.
If I had to guess, I'd imagine that Chrome stores the things that I type in the URL bar in a trie whose values are the number of times that a particular string has been typed (and/or visited ?). Then I'd imagine it has some sort of exponential decay model for the "counts" in the trie. But this is just a guess. Does anyone know how this updating process happens ?
Well, I ended up finding some answers by having a look at the Chromium source code ; I'd imagine that Chrome itself uses this code without too much modification.
When you type something into the search/URL bar (which is apparently called the "Omnibox"), Chrome starts looking for suggestions and completions that match what you've typed. To do this, there are several "providers" registered with the browser, each of which knows how to make a particular type of suggestion. The URL history provider is one of these.
The querying process is pretty cool, actually. It all happens asynchronously, with particular attention paid to which activity happens in which thread (the main thread being especially important not to block). When the providers find suggestions, they call back to the omnibox, which appears to merge and sort things before updating the UI widget.
History provider
It turns out that URLs in Chrome are stored in at least one, and probably two, sqlite databases (one is on disk, and the second, which I know less about, seems to be in memory).
This comment at the top of HistoryURLProvider explains the lookup process, complete with multithreaded ASCII art !
Sqlite lookup
Basically, typing in the omnibox causes sqlite to run this SQL query for looking up URLs by prefix. The suggestions are ordered by the number of visits to the URL, as well as by the number of times that a URL has been typed.
Interestingly, this is not a trie ! The lookup is indeed based on prefix, but the scoring of those lookups does not appear to be aggregated by prefix, like I'd imagined.
I had a little less success in determining how the scores in the database are updated. This part of the code updates a URL after a visit, but I haven't yet run across where the counts are decremented (if at all ?).
Updating suggestions
What I think is happening regarding the updating of suggestions -- and this is still just a guess right now -- is that the in-memory sqlite database essentially has priority over the on-disk DB, and then whenever Chrome restarts or otherwise flushes the contents of the in-memory DB to disk, the visit and typed counts for each URL get updated at that time. Again, just a guess, but I'll keep looking as I get time.
The code is really nice to read through, actually. I definitely recommend it if you have similar questions about Chrome.
I have a pretty good project task management system going in Microsoft Access, but one feature I'm still missing is some type of 'quick entry' like facility often found in many good productivity applications.
This is how it would work:
Scenario 1:
You're in another application, working on a few things, and you just remember something that needs to get done. You hit your predefined shortcut: CTRL + ALT + T (again, from outside Microsoft Access) and it brings up a small access form with a text box in to which you can type what needs to get done, e.g.
Inform key stakeholders of concerns regarding timeline
you hit return and that gets saved as a record in Microsoft Access instantly.
An alternative, and slightly more complex scenario...
Scenario 2:
As above, but you want to add further details besides the task name, such as the person you need to speak to, and a due date. The input in to the text box could look like this:
Inform #Sally of concerns regarding timeline >+3
Where '#' tells access to populate a field called 'Contact' with 'Sally' (unless it already exists) and '>+3' is interpreted by access to mean a due date 3 days from today.
How difficult are Scenario 1 and Scenario 2 to perform? What level of VBA/programming knowledge would be required?
Thanks,
I would say it requires a fair amount of confidence in VBA.
You need to register a global hot-key; that is, a keyboard-combination that can be captured from outside the Access application. It requires win-api calls. Here is some code.
You need to know where to place these calls. I believe you have to put them in a standard module, not in the form's class module. (I haven't double-checked this, it's late.)
You need to have a little understanding about what this code is doing. NEVER attempt to type this api-code - copy it from a reliable source, exactly as it is!! You don't need to fully understand the code, but you need to know how (and when) to call each function.
Once you've registered the hot-key then your VBA needs to bring your application to the front and display your form, and focus it. Reliably bringing the application to the front may also require api-calls.
Once your form is opened (and focused) you can have a button on it to parse the information in its textbox. However, if you are designing the form anyway, I would add checkboxes, comboboxes, etc., rather than trying to parse a complex sentence/ statement.
For a major school project I am implementing a real-time collaborative editor. For a little background, basically what this means is that two(or more) users can type into a document at the same time, and their changes are automatically propagated to one another (similar to Etherpad).
Now my problem is as follows:
I want to be able to detect what changes a user carried out onto an HTML textfield. They could:
Insert a character
Delete a character
Paste a string of characters
Cut a string of characters
I want to be able to detect which of these changes happened and then notify other clients similar to "insert character 'c' at position 2" etc.
Anyway I was hoping to get some advice on how I would go about implementing the detection of these changes?
My first attempt was to consider the carot position before and after a change occurred, but this failed miserably.
For my second attempt I was thinking about doing a diff on the entire contents of the textfields old and new value. Am I missing anything obvious with this solution? Is there something simpler?
It is a really hard work make this working today, for several reasons, but
maybe you will need to restrict only to some browsers. read: https://developer.mozilla.org/en/XUL/Attribute/oninput the alternative to "oninput" is listen to all input events (keyboard, mouse, dragdrop) I suggest to use "oninput"
html is not perfect... even html5. input and textareas supports only single-range
selections. you can solve this using designmode/contenteditable instead of
textareas/textfield
detecting offsets of what changed is a hard work: read
-- https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/window.getSelection
-- http://www.quirksmode.org/dom/range_intro.html -- http://msdn.microsoft.com/en-us/library/ms535869%28v=VS.85%29.aspx -- http://msdn.microsoft.com/en-us/library/ms535872%28v=VS.85%29.aspx
you may need a "diff" algorithm written in javascript! http://ejohn.org/projects/javascript-diff-algorithm/
one personal note: detecting words, characters changes may be totally non-sense and not useful, detect instead paragraphs changes, or in case of an excel-like worksheet, the single cell
I hope this helps
feel free to correct my English!
My pseudocode/written out response would be (if I understand your question exactly) to use jQuery to detect keyup events and then save the input to the server via ajax, then also take the response and post it back to the input. This isn't very efficient, but basically the idea is that you're constantly posting and checking what else has been posted. If you want to see what someone else is doing in real time, you can ping the server every second or so and update with the response.
All of this of course can be optimized, but it still is kind of taxing for a server. You could also see if you can implement Google Topeka Wave for your project, or get in touch with Google Topeka to see how they do it :)