I don't know how to title this thread, forgive me if it's bad.

I'm trying to determine the best way of handling this and I'm getting nervous about it.

The basic setup I have is a server system that is run when the application is open (it's not a service, but a winforms app). The server form shows (among other things) a button to start and stop the server, and a rich text box showing the activity of the server and the clients connected to it.

Standard modeling for something like this (I think) suggests 3 layers. A UX layer(or GUI layer for you old farts), a logic layer (the methods used to interact with the data...the core of the server really), and the data layer (in this case a SQL server).

In my situation, the UX is a win form app, the logic is a dll which bridges the UX layer to the data layer.

Since each connection to the server will run on its own thread, what is the best way for those threaded connection instances to access the logic layer to update, delete, get data etc...basically "talk" to the server? I was going to put on my UX form a static instance of the logic layer (the dll) and just have the threads use that, but I'm worried that if I do that, the UX layer will "hang" while methods are called from it. That can't happen.

So I guess the nutshell question is, if I do this on the UX form:

private static MyServer.LogicLayer _MyLogic = new MyServer.LogicLayer();

public MyServer.LogicLayer MyLogic
{
    get { return _MyLogic; }
}

and a different thread (that was started by the UX form thread) does something like this:

DataSet MyDataSet = UxForm.MyLogic.MyServerMethod();

is the whole world going to fall apart? Errr...I mean, will the server form hang if it takes a while for the method to finish (also there could be multiple calls from multiple threads to the same method!) I just can't see creating an instance of the MyServer.LogicLayer on each new thread...maybe I need to?

Please...I need suggestions.

Recommended Answers

All 4 Replies

Yes, it's going to fall apart. By having just one connection to the database like this it's possible for multiple threads to place the connection in various states, interrupt threads that are trying to read/write the database, etc.

Create a new connection for each thread. The way the .NET database code is designed it already allocates ten connection threads (I believe it's 10, could be 20) automatically (you don't have access to them directly, it does the assigning behind the scene as you create new connection objects).

Thread safe database code can be very tricky, as you need to ensure that no one is doing an update when one thread is doing an update, no one is reading when you are updating, etc. Some of this the database can handle but you do need to keep it in mind as you code.

Yes, it's going to fall apart. By having just one connection to the database like this it's possible for multiple threads to place the connection in various states, interrupt threads that are trying to read/write the database, etc.

Create a new connection for each thread. The way the .NET database code is designed it already allocates ten connection threads (I believe it's 10, could be 20) automatically (you don't have access to them directly, it does the assigning behind the scene as you create new connection objects).

Thread safe database code can be very tricky, as you need to ensure that no one is doing an update when one thread is doing an update, no one is reading when you are updating, etc. Some of this the database can handle but you do need to keep it in mind as you code.

Momerath,

Maybe I explained it poorly. Let me try to clarify a bit.

There are three parts here:
Server Manager - An executable that presents a user interface for the server.
Server Core - A dll file that contains methods and information on how clients can communicate with the server (the protocols, the available commands etc...)
SQL Server - this stores the data, and is ONLY accessed by the methods in the Server Core.

When the user clicks the button to start the server on the form it creates a new thread, and on that thread it executes a method contained in the Server Core that listens for connections on whatever socket it's set-up to.

When a client sends a request to connect, the thread that's listening for connections spins off a new thread that will authenticate the user and then establish a tcp socket connection.

Let's say for example, we have one server and 10 users connect to that server. That would mean there are 12 threads running on the server, 1 for the GUI server manager, 1 listening for new connections and 10 for each user connected.

When connection #1 needs data, it doesn't send a SQL command to the server, it sends a command using my server's protocol. The thread thats running connection #1 passes that command to the Server Core, the Server Core interprets it, executes SQL commands (if needed) and returns the result to the thread. The thread does post-processing (if needed) and returns the result to the client.

The question is, does each thread with a user connection (the 10 threads) need it's own instance of the Server Core? Or is it possible to create a single instance that they all share?

I know about the data inconsistencies problems that you are talking about. Believe me I've spent a lot of time worrying about that as well. But a new connection WILL be made to the database for each connection. The Server Core, when it interprets what the command is, will generate the appropriate SQL statements and execute them on a new connection.

I guess what I'm saying is, each method in the Server Core that requires communication with the SQL server will use a new "physical" connection.

I dunno...maybe I'm not good at explaining this one. But I hope that helped?

No, each of the threads does not need it's own Server Core as long as calls to Server Core are thread safe. You can even use only one connection if you want, as long as the Server Core code queues up requests rather than trying to push them all through at once.

You will probably have to consider some form of queuing or locking in case of read/write requests.

True.

Maybe a queue would work best, and the server core can just check a flag to see if there are commands pending and execute them as needed.

This should be interesting... *holds an envelope to his head* hmmm...I see great problems in my future...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.