This is the first time I'll be using OpenAccess in a Windows Forms project.
I'm writing a game server which will load Player objects from the database using OA. these Player objects should remain in memory until the server shuts down.
Question: Is it OK to keep a single ObjectScope during the lifetime of the application? Or should I dispose the ObjectScope as soon as possible?
7 Answers, 1 is accepted
I haven't tested it yet, but will update this thread should I come across any issues.
We are glad you found a solution. You have located the right sample application. As you can see there are two options to proceed with reverse mapping. The example is based on the Visual Designer Entity Diagrams context. However, it can be generalized for the IObjectScope. Bear in mind that with the Entity Diagrams context you can accomplish the same scenarios as with the IObjectScope. One of the benefits of using the Entity Diagrams context is that transaction management is transparent to the programmer and you do not need to explicitly start a transaction or specify transaction settings in order to commit changes.
There are different scenarios for using the IObjectScope. Usually, it is recommended that you keep one scope per thread. You should take into consideration how often you will update objects you retrieve. If you have one long-living object scope in the application and there are multiple applications running at the same time querying the same database then some additional effort is needed to manage the updates consistently across applications. If you need only a snapshot of the database instance and you are confident that there will rarely be updates, you can create an object scope and dispose of it eagerly (in a using statement). You can also use a short-living scope to manage some brief operations independent of the current state of the database – for example, adding new records.
In your case, if I understand you properly, you need to retrieve a collection of players which should be resident in memory. You can benefit from the second level caching mechanism Telerik OpenAccess provides. You can have a look at the following blog posts:
the Telerik team
Thanks for the info!
Just to be sure, what would you advise for the following scenario:
- A player logs in into the game server (windows forms application) and provides a username and password.
- The server will load the Player object with the specified username and password and adds it to the game simulation (which has a list of Player objects). This player should be there as long as the application is running or until the player disconnects
At this point, if I dispose the IObjectScope, I cannot access any property of the loaded Player object, because I will receive an InvalidOperationException with message: "IObjectScope is already closed".
So this means I need to maintain the ObjectScope for the life of the application. I will have to do updates regularly (not only to the Player objects, but also to other game objects, like world state). If I understand correctly, I can safely store the IObjectScope in a thread. Will that still be OK even though the IObjectScope might be alive for 72 hours? Or do you have another suggestion for this case, for example, the ObjectContainer?
You are right about the disposal of the IObjectScope. Let me provide some further details on the topic. Whenever you need to access or modify a property of an object retrieved by an IObjectScope you need to have the same object scope active.The ObjectContainer is best suited for web scenarios. Its main benefit is that it is serializable and you can transport objects easily across the network without the need to worry about synchronization issues. Therefore, a disconnected environment with asynchronous interaction is where the ObjectContainer really shines. In your case you need to handle a collection of objects which are retrieved in memory. Enabling the second level caching mechanism can provide you a great boost to performance as you can retrieve commonly used objects fast.
The one-scope-per-thread approach is fine in your case and this is the scenario that is recommended for most of the cases. As long as this holds, it is not a problem for the scope to exist for a long time. The connections to the database are managed with connection pooling so the only thing you need to worry about is how to correctly reflect changes made by other threads’ scopes. Each scope has its own level one cache. When you call the scope.Transaction.Begin() method the cache is refreshed when the option RefreshReadObjectsInNewTransaction is set to true. This is the default behavior. If you modify some of the commonly used objects with other scopes you need to refresh the objects in this cache by calling the refresh method of the scope. This step is necessary when you display objects in the UI which haven’t been updated for a long time. The long-living scopes need to be reminded that there are changes made by other scopes.
Again, let me remind you that with the Entity Diagrams context transaction management is handled automatically. Besides, you can retrieve objects from this context, dispose of it, access the properties of the objects and even make changes but you cannot commit them directly. You still need to retrieve corresponding objects from a context and update them while the context is active.
You can browse our online documentation for related topics:
If you want to know more about the ObjectContainer you can have a look at the following blog post
Should you need further assistance, do not hesitate to contact us back.Greetings,
the Telerik team
That puts everything into perspective, thanks!
I will read more about and experiment with the entity Diagrams context, it sounds like it will ease the managing of transactions and objectscopes for me.
The 2nd level cache was actually the primary reason for me to obtain OpenAccess in the first place, but until just now I didn't realize the benefit of it in multithreaded applications (actually, I confused the 1st level cache with the 2nd level cache, not realizing that the 1st level cache only lives as long as the objectscope does). In my application, there will be a game server (winforms on the server) and an asp.net application, both talking to the same database. I guess for this situation I would benefit from using the 2nd level clustered cache, since the 2nd level cache is scoped per Application, and the clustered cache will synchronize with each cache instance.
Thanks a lot for all the helpful information, it's appreciated!
You have once again correctly found the appropriate scenario for your application. Indeed, the second level clustered cache will handle the synchronization between the two application servers. I suppose you have browsed our documentation and you are familiar with the prerequisites.
Do not hesitate to contact us again for any questions that may arise.
the Telerik team