Multithreading in opennetcf.orm (how to use SqlCeDataStore) - c#

I just started using the OpenNETCF.ORM framework, and I ran into a problem. What is the correct way to use SqlCeDataStore in a multithreaded application?
In a single-threaded application I would simply use a static field:
public class MyApp
{
private static SqlCeDataStore _store;
public static SqlCeDataStore Store
{
get {
if (_store == null) {
_store = new SqlCeDataStore("database.sdf");
// other initialization stuff, DiscoverTypes() etc...
}
return _store;
}
}
}
And then I would use it like so:
var customers = MyApp.Store.Select<Customer>().ToArray();
After some research on SQL Server Compact, I found out that connections aren't thread safe, so each thread should have it's own connection. OpenNETCF.ORM does have an option to use a new connection each time you connect to the database. Should I just use that?
Another option would be to create a new SqlCeDataStore for each thread. Is that better?
What is the correct way?

We use SQL Compact in a variety of heavily multithread applications using the OpenNETCF ORM without any problems. We run these on full Windows and Windows CE.
We use the "Maintain Maintenance Connection" connection behavior, where a new connection is created for all CRUD calls, but a single-background one is kept for doing maintenance work (creating tables, etc). This gives good performance and a reasonable amount of thread safety.

Related

Accessing objects created in windows service

If I was to create a windows service, which in the background was making calls to the database and populating various objects. Is it then possible to access these objects from a standalone C# application? If so, how would I do this?
Thanks
Simply you can use Named Pipes to make communication between two .Net applications.
This should be place inside Service to listen on client applications request
private static void SendByteAndReceiveResponse()
{
using (NamedPipeServerStream namedPipeServer = new
NamedPipeServerStream("test-pipe"))
{
namedPipeServer.WaitForConnection();
namedPipeServer.WriteByte(1);
int byteFromClient = namedPipeServer.ReadByte();
Console.WriteLine(byteFromClient);
}
}
and this will be inside Client applications
private static void ReceiveByteAndRespond()
{
using (NamedPipeClientStream namedPipeClient = new
NamedPipeClientStream("test-pipe"))
{
namedPipeClient.Connect();
Console.WriteLine(namedPipeClient.ReadByte());
namedPipeClient.WriteByte(2);
}
}
Note
Please do changes in
namedPipeClient.WriteByte(2);
according to your business logic.
OR
Please read this thread
Accessing objects strictly speaking is not possible. You can connect your apps with (for example) named pipes as per #Taha Sultan Temuri and serialize your objects, send over and deserialize them on the other end.

Use static global variable class in ASP.NET MVC web application

I am creating an ASP.NET MVC web application. It has service classes to execute business logic and it access data through Entity Framework.
I want to change some business logic based on application variable. These variables are global variables and load from app config and don't change after the initial loading.
public class BroadcastService : IBroadcastService
{
private static readonly ILog Logger = LogProvider.GetCurrentLogger();
private readonly IUnitOfWork _worker;
private readonly IGlobalService _globalService;
public BroadcastService(IUnitOfWork worker, IGlobalService globalService)
{
_worker = worker;
_globalService = globalService;
}
public IEnumerable<ListItemModel> GetBroadcastGroups()
{
if(Global.EnableMultiTenant)
{
//load data for all tenants
}
else
{
//load data for current tenant only
}
return broadcastGroups ?? new List<ListItemModel>();
}
...
}
public static class Global
{
public static bool EnableMultiTenant{get;set;}
}
For example, EnableMultiTenant will hold application is running in multi-tenant mode or not.
My concerns are:
Is it ok to use a static global variable class to holds those values?
This application is hosting on Azure app service with load balancing. Is there any effect when running multi-instance and when app pool restarts?
To answer your question as to whether it is 'okay' to do this, I think that comes down to you.
I think the biggest thing to know is when that data is going to get refreshed. From experience I believe that static information gets stored in the application pool, so if it is restarted then the information will be refreshed.
Lifetime of ASP.NET Static Variable
Consider how many times you need that information, if you only need it once at startup, is it worth having it as a static. If you are getting that information a lot (and say for example it is stored in a database) then it may be sensible to store that in a cache somewhere such as a static member.
I think my only recommendation with static member variables is asp is keep them simple, booleans seem fine to me. Remember that users do share the same application meaning that static variables are global for all users. If you want a user specific variable then you want to use sessions cache.
Always remember the two hardest thing in programming
Naming things
Cache invalidation
Off by one errors
https://martinfowler.com/bliki/TwoHardThings.html
Even though this is a joke, it holds a lot of truth
Hope this helps
This is thread safe if you initialize these values once and then only read from them. It is also safe in the presence of multiple worker processes and restarts because the multiple processes don't share variables.
As an alternative consider creating an instance of a class holding your settings:
class MySettings {
bool IsEnabled;
}
Then you can use dependency injection to inject a singleton value of this class to your code. This makes it easier to tests and makes the code more uniform.

Windows Phone 8 localdb thread safety

I have a WP8 app that has multiple (at times, up to 40) threads that have to get the data from a webservice and then commit to a localdb.
I have implemented an AutoResetEvent-based pattern where each Repository method looks somewhat like this:
public class MySuperAppRepository
{
public static AutoResetEvent DataAccess = new AutoResetEvent(true);
public MyFancyObject CreateMyFancyObject(string path, int something)
{
DataAccess.WaitOne();
try
{
using (var dbContext = new MySuperAppDataContext(MySuperAppDataContext.DbConnectionString))
{
var mfo = new MyFancyObject();
dbContext.MyFancyObjects.InsertOnSubmit(mfo);
mfo.Path = path;
mfo.Something = something;
dbContext.SubmitChanges();
return mfo;
}
}
finally
{
DataAccess.Set();
}
}
}
This is all nice and clean, but as soon as i get multiple threads (as mentioned above), the performance is PATHETIC. i can get lots of requests come down and then they're all waiting for db to be free.
Is there a better alternative? Would using lock(object) improve the performance?
Can you try not creating a new DataContext on every data operation.
Also try out some of the best practices mentioned here.
in particular :
Enabling fast updates with a version column
One of the easiest ways to optimize the performance of an update operation on a table is to add a version column. This optimization is specific to LINQ to SQL for Windows Phone. For example, in an entity, add the following code.
[Column(IsVersion=true)]
private Binary _version;

Is locking single session in repository thread safe? (NHibernate)

I read many posts saying multithreaded applications must use a separate session per thread. Perhaps I don't understand how the locking works, but if I put a lock on the session in all repository methods, would that not make a single static session thread safe?
like:
public void SaveOrUpdate(T instance)
{
if (instance == null) return;
lock (_session)
using (ITransaction transaction = _session.BeginTransaction())
{
lock (instance)
{
_session.SaveOrUpdate(instance);
transaction.Commit();
}
}
}
EDIT:
Please consider the context/type of applications I'm writing:
Not multi-user, not typical user-interaction, but a self-running robot reacting to remote events like financial data and order-updates, performing tasks and saves based on that. Intermittently this can create clusters of up to 10 saves per second. Typically it's the same object graph that needs to be saved every time. Also, on startup, the program does load the full database into an entity-object-graph. So it basically just reads once, then performs SaveOrUpdates as it runs.
Given that the application is typically editing the same object graph, perhaps it would make more sense to have a single thread dedicated to applying these edits to the object graph and then saving them to the database, or perhaps a pool of threads servicing a common queue of edits, where each thread has it's own (dedicated) session that it does not need to lock. Look up producer/consumer queues (to start, look here).
Something like this:
[Producer Threads]
Edit Event -\ [Database Servicer Thread]
Edit Event ------> Queue -> Dequeue and Apply to Session -> Database
Edit Event -/
I'd imagine that a BlockingCollection<Action<Session>> would be a good starting point for such an implementation.
Here's a rough example (note this is obviously untested):
// Assuming you have a work queue defined as
public static BlockingCollection<Action<Session>> myWorkQueue = new BlockingCollection<Action<Session>>();
// and your eventargs looks something like this
public class MyObjectUpdatedEventArgs : EventArgs {
public MyObject MyObject { get; set; }
}
// And one of your event handlers
public MyObjectWasChangedEventHandler(object sender, MyObjectUpdatedEventArgs e) {
myWorkQueue.Add(s=>SaveOrUpdate(e.MyObject));
}
// Then a thread in a constant loop processing these items could work:
public void ProcessWorkQueue() {
var mySession = mySessionFactory.CreateSession();
while (true) {
var nextWork = myWorkQueue.Take();
nextWork(mySession);
}
}
// And to run the above:
var dbUpdateThread = new Thread(ProcessWorkQueue);
dbUpdateThread.IsBackground = true;
dbUpdateThread.Start();
At least two disadvantages are:
You are reducing the performance significantly. Having this on a busy web server is like having a crowd outside a cinema but letting people go in through a person-wide entrance.
A session has its internal identity map (cache). A single session per application means that the memory consumption grows as users access different data from the database. Ultimately you can even end up with the whole database in the memory which of course would just not work. This requires then calling a method to drop the 1st level cache from time to time. However, there is no good moment to drop the cache. You just can't drop in at the beginning of a request because other concurrent sessions could suffer from this.
I am sure people will add other disadvantages.

Locking an ASP.NET application variable

I'm using a 3rd party web service in my ASP.NET application. Calls to the 3rd party web service have to be synchronized, but ASP.NET is obviously multi-threaded and multiple page requests could be made that result in simultaneous calls to the 3rd party web service. Calls to the web service are encapsulated in a custom object. My thought is to store the object in an application variable and use the C# lock keyword to force synchronized use of it.
I'm nervous, because I'm new to multi threaded concepts and I've read that you shouldn't lock a public object (which my application variable effectively is). I've also read that if the locked block of code fails (which it could if the web service fails), then it could destabilize the app domain and bring down the application.
I should mention that the 3rd party web service is rarely used in my website and it's going to be rare that 2 requests to it are made at the same time.
Here's a rough code sample of how I'd make calls to the web service:
ThirdPartWebService objWebService = Application["ThirdPartWebService"] As ThirdPartWebService;
lock (objWebService)
{
objWebService.CallThatNeedsToBeSynchronized();
}
You should create a private static readonly object _lock = new object(); in the class that makes the webservice calls, and use that as a lock. Since the object is static there will only be one of them throughout all of your application, a Singleton object if you wish (http://en.wikipedia.org/wiki/Singleton_pattern)
public class MyWebServiceWrapper
{
private static readonly object _lock = new object();
public void CallWebService()
{
lock(_lock)
{
var objWebService = (ThirdPartWebService)Application["ThirdPartWebService"];
objWebService.CallThatNeedsToBeSynchronized();
}
}
}
If your class that makes the WebService call doesn't do anything else, you can also just make a lock on this (lock(this)). Just remember, that this will mean, that if you have several methods, the call to one method will block all the other methods as well, which is why you normally shouldn't lock this.
If it is vital you should only have a single call to the service at any time I recommend you write your own Windows Service. This depends on how much fault tolerance you want.
Let's say for example you make a call to the web service, but then the application pool is recycled. When a new request comes in it would be handled by a new instance of your application which could then make the call to the web service (Even if the other instance is running).
You could pass this off to a windows a service, then use a polling mechanism from the client to check if the service has finished (Client would ask IIS are you done, IIS would look for some indication from windows service that it was done). This approach will avoid locking anything in IIS, and you won't waste critical resources such as threads in your thread pool waiting on a third party service.
You should never lock on a single resource in your web application...it's just too risky.
Edit
Another option is to use the Monitor object directly:
if (System.Threading.Monitor.TryEnter(syncObj,10))
{
try
{
//CallWebService
}
finally
{
System.Threading.Monitor.Exit(syncObj);
}
}
else
{
//Tell Client they are still waiting
}
TryEnter will block until a lock is made or 10 milliseconds has passed. You could then in your timeout tell the client they need to retry. You could then have your client code decide if it should reissue the request. You could also use a semaphore or mutex (forget which one is more appropiate here). But it would assuming you have permissions to use them, give you something you can lock on at the machine level which would prevent the app recycling use case.
You can lock on a static shared object. This is a common way to use lockĀ“s in .Net. By using a static object you know it will be shared among all threads, and the lock is ensured.
As for making the app unstable if the call fails, that has to be due to the call not disposing properly. By using the "using" statement you are ensuring that dispose is called at the end of the call. Read this SO thread on why/why not you should dispose a web service regarding performance.
static readonly object _lockObj = new object();
...
lock( _lockObj )
{
ThirdPartWebService objWebService = Application["ThirdPartWebService"] As ThirdPartWebService;
objWebService.CallThatNeedsToBeSynchronized();
}
lock() will not prevent multiple call to your webservice. It will only ensure that no thread is executing code block within lock() {} at the same time.
So the the question is what does that webservice do?
1) Performs some action on third party (updates their DB with some values you supply?)
You can do as you've yourself suggested. Though I would say that if their service cannot handle simultaneous calls, then they should fix it. Thats really not your problem to worry about.
2) It queries and returns some data for your use.
In this case lock is useless unless you plan on caching the result of the call.
var cachedValue = ReadValueFromCache();
if (cachedValue != null)
return cachedValue;
lock (objWebService)
{
// yes you need to do it second time inside the lock
cachedValue = ReadValueFromCache();
if (cachedValue != null)
return cachedValue;
cachedValue = objWebService.CallThatNeedsToBeSynchronized();
SaveValueToCache(cachedValue);
}
return cachedValue;
How you implement the cache is kinda secondary. It maybe web cache object or just a static variable.

Categories

Resources