Update client-PCs with each others activities (insert, update, delete) - c#

I am developing a Client-Server application using C# .NET Winforms with SQL Server 2008. The client pc's connect to the database server via the LAN.
The task I want to achieve is when an insert (or update or delete) is performed on one client-PC, all other clients must get that update in real-time.
I am currently using timers, so that each client queries the database every 15 seconds then refreshes the gridviews, combo boxes and list boxes. But this makes the application slow and bulky to use.
What is the correct method to use in such scenario. What are such operations called (correct terminology)? Should I use windows services? or same application with background threads ?

First of all, its Windows, so it cannot ever be realtime.
The solutions that – Igby Largeman suggests is well possible. It does have the disadvantage that it can cause very heavvy network traffic, because every time something changes in the database, it is broadcasted to all the clients.
You also have to consider the possibility that something clogs ub the communication between the server and one or more clients, so realtime is out of the question.

that's tricky!
If you really want a user with a grid open on PCA to see data inserted on a PCB without performing any action, you will need a timer to refresh the grid. But I dont think this is a good aproach, you can easily overload the system.
The good practice here is display only the data due to be manipulated. So for example, lets say you want to alter a client's name. You build a search form with a grid where the user can inform search parameters (to filter the data) and once the client is found and altered, you perform another search to the DB to get and display the new data.
But lets say another user had the same grid open showing the client before you perform the alteration. It is showing the old value, but once it clicks on it to see the details, you'll perform a search to the DB to get the new data so that would be ok.

Related

Web application + SQL server triggers / thresholds

We have a web application that is hosted in IIS. In our database that serves the application we have all kinds of different data values. We are trying to figure out a way to have an email sent to a client if a certain data value exists or exceeds a threshold value.
Generic Example:
Say we have a table that lists widgets and their 'in inventory' quantity. Every time someone sells a widget, this quantity value would be depleted. We want to send an email to the manager when the widget quantity gets below 5 and tell him to reorder more widgets.
We don't want to have sql triggers that check the quantity any time a 'depletion' transaction takes place. Instead, we want some type of background monitoring process that checks the level of the widgets on a timed basis. How can we accomplish this? Windows Service / WinForm application? Something built into IIS that will run ASP.net C# code?
Polling based monitoring should be your last resort. It uses too many resources for a simple task and most of the time it will only see that it's not the case to do anything. And it doesn't even scale when your data grows.
Instead, you should focus on the code that changes those values and act then, on in spot. And the check will also be lighter: only one item being checked not all, and only once, not every x seconds/minutes/hours/...
Apart from the architectural considerations, to answer your question, just as Jonathan said: anything that can read a database and send emails will do, but I'd consider a Windows Service for this job because that's what they were made for: background jobs running all the time, unrelated to the host users. You also get some extra benefits like automatic startup and recovery options.
Anything that can read the database and send an email could accomplish this - console app, winforms app, web app -- it doesn't really matter.
It may be more efficient to monitor when the values are changed (what changes them? A web application?) and have that application also send notifications

Multiple Clients on 1 server

I am new to GUIs, and i have encountered a problem in my client-server program.
My program is like a "customer-support", where multiple clients can use it from different computers simultaneously.My problem is that when one client changes some info, its inserted into the db but the other client will not see it unless I add a "Refresh" button to my gui.
I want the gui to be dynamic and react to different clients actions. How can you come over this issue?
EDIT:
1. .net4,
2. sql-server,
3. The actions happends after a button click
Basically, you have two options: push or poll. Push (some central server announcing the change to all the listeners) is more immediate, but demands suitable infrastructure. It also depends on the number of clients you need to support, and how many events are passing through the system. Personally, I'm a big fan of redis pub/sub for this (it is actually what we use for the live updates here on stackexchange, coupled with web-sockets). But in some cases you can get the database to provide change notifications directly (personally I prefer not to use this). You may also be able to use events over something like WCF from a central app-server, but that depends on there only being one app-server, which doesn't sound like a good idea to me.
The other option is polling - i.e. have the application automatically query the system periodically (every minute perhaps) to see if the data being displayed has changed. If you can, using the timestamp/rowversion is a cheap way of doing this.

Multi-User Database Desktop Application Design

First, I apologize for the seemingly dumb question I'm not very strong with databases.
I'm re-designing a desktop application in C# for use over a local network that basically is a highly specialized ticket tracking system. Essentially when a user launches the application they'll be asked for their credentials to gain access to the system and then the application will query the central database for data (currently a MySQL server running on a local machine), displaying it on the screen.
My question is if four users are connected and two users enter new data, what is the most efficient method of letting each user know of the new data? Would it be simply to query the database and update the application with the new data on a timer? Or would creating a server application to sit in between the user and the database server to perform queries itself and notify each connected user of updated data?
See it all depends how important is it to notify the clients in real time about the changes in your database. If your clients have no issue with a delay of minute or two you can probably go for the timer approach. But if they really wish the data to be real time (delay of less than 1-2 sec), go for the other approach. Create a separate service which polls the database and notify the client application for any update. For this you can make use of socket listners.
Hope that helps !!
4 users? On a local LAN? Using simple, indexed queries? Just poll the DB from the clients. Kick off a thread at application start up and have it run a query every 2-5 seconds, then notify the user using whatever is appropriate for background threads updating GUIs in .NET.
This is straightforward, don't over think it. The "hardest" part is the asynchronous notification of the user (which depending on your GUI layout and required actions is probably not a big deal either, thus the quotes).

Refreshing Windows program when other users make changes?

Scenario:
4 users launch separate instances of the same client program (Winforms) that is connected to a database based To-Do list.
The first user selects the 3rd To-Do list item.
How do I update/refresh the other 3 users screens to reflect that item #3 is no longer available?
My thought was a table that contains the last update date-time stamp. Then a timer would check every few seconds to see if there have been any changes.
UPDATE1:
Thanks to all - there are definitely a number of valid answers.
I went with simpler version of the scenario that Icemanind recommended.
As Lucas suggested you can implement a 'Push' style system that whenever an entity is modified it is 'Pushed' to the other connected users. This can be a bit complex. Working with a legacy system the way we handle this is through a 'Change Number' column but really it can be anything that is updated each time the record is modified.
When a user attempts to modify an entity we query the database to row-lock that entity where the 'Change Number' reflects the 'Change Number' the user currently has.
If the lock is successful the user is able to update/delete the entity. When they are done they 'Save/Commit' and 'Change Number' on the entity is increased.
If they fail to get the row-lock and the 'Change Number' was the same, we display a message that the entity they requested is in use by another user. If the 'Change Number' was different then the message states they must refresh their view.
Yes. The best way to do this is to implement a "push" type system. Here is how it would work. Whenever someone clicks something on the client end, the client would send a message to the server. The server would need to receive this signal and then the server would send out a refresh message to all clients connected to the server.
I don't know your client or server is coded, but you'll want to create a thread on the server that "listens" for incoming messages from clients and once it receives a message, puts it into a queue, the returns to listening for more messages. A second thread on the server needs to process the messages in the queue.
On the client side, you'll also want a second thread that listens for incoming messages from the server. Once a message is received, it can process the message and take whatever action is necessary.
A pretty decent tutorial on client/server and socket programming can be found here: http://www.codeproject.com/KB/IP/serversocket.aspx
Of course, it is a guide. You will need to modify it as you see fit.
Hope this makes sense and good luck!
You could implement a 'Push' system where when 1 user updates something, the server sends an update message to all connected clients.
I'd opt for an isDirty timestamp/flag on the items. No need to get all the items again and no need to create a difficult push system. Reread the items since last call every now and then.
If you're using SQL Server as your store, and ADO.NET or something on top of that for your data access, you should also check into SQL Dependency.
Basically, you can create a query from a table, and you can instruct SQL Server to notify you if any of the data in that query result changes.
See some intro articles on the topic:
Using SqlDepedency for data change events
SqlDepedency: creating a smarter cache
Using SqlDependency to monitor SQL Database changes
Query notifications in ADO.NET 2.0
It requires a bit of initial setup effort, but the huge advantage here is: you'll be notified automagically when something you're interested in (which is part of your query result set) changes, and you can react to that. No messy polling or anything....

How do I get a Windows Form client to update every time a SQL Server table changes?

I have a form with a list that shows information from a database. I want the list to update in real time (or almost real time) every time something changes in the database. These are the three ways I can think of to accomplish this:
Set up a timer on the client to check every few seconds: I know how to do this now, but it would involve making and closing a new connection to the database hundreds of times an hour, regardless of whether there was any change
Build something sort of like a TCP/IP chat server, and every time a program updates the database it would also send a message to the TCP/IP server, which in turn would send a message to the client's form: I have no idea how to do this right now
Create a web service that returns the date and time of when the last time the table was changed, and the client would compare that time to the last time the client updated: I could figure out how to build a web service, but I don't how to do this without making a connection to the database anyway
The second option doesn't seem like it would be very reliable, and the first seems like it would consume more resources than necessary. Is there some way to tell the client every time there is a change in the database without making a connection every few seconds, or is it not that big of a deal to make that many connections to a database?
Try the SqlDependency class. It will fire an OnChange event whenever the results of its SqlCommand change.
EDIT:
Note that if there are large numbers of copies of your program running, it can generate excessive server load. If your app will be publicly available, it might not be a good idea.
Also note that it can fire the event on different threads, so you'll need to use Control.BeginInvoke to update your UI.
You can use Event Notifications in SQL Server to raise events in .Net letting you know that the data has changed. See article linked below.
Eric
SQL Server Event Notification
With ASP.Net you can cache query results in memory and setup a dependency that registers with the SQL Server. When something within the data changes the cache is refreshed automatically. Perhaps looking into this might point you in a good direction.
http://msdn.microsoft.com/en-us/library/ms178604.aspx

Categories