|
|
|
Current Scenario:
I have a long running application that gets a job list from sql, creates a child process for each request and exchange status data with those child process with a full-duplex communication.
All processes runs on the same machine as the host application, currently all processes are Win32 and I use WM_COPYDATA.
Future:
It is likely that in the next future the Win32 application will be rewritten to .NET, child processes will remain untouched, new child processes will be written in any language/platform (.NET, Win32) depending on 3rd party specifications/libraries.
Question:
I would like to hear some rant on how to implement interprocess communication between .NET and Win32 application.
TIA
|
|
|
|
|
You could convert the WM_COPYDATA-solution to a C#-counterpart. Windows-messaging is fast, and you'd retain compatibility with the old version.
Alternatively you could use a HttpServer, and use WebRequests; easier to debug than Windows-messages, and you can send/receive messages from beyond the local desktop.
I are troll
|
|
|
|
|
This is a simple class I am building to abstract some functionality. Pay attention to my use of assertions.
///
/// Encapsulates execution of queries.
///
public class QueryExecutor
{
/// summary
/// Returns a DataTable object populated using the specified parameters.
/// summary
/// param name="connectionString" // the connection string to use
/// param name="queryType" //
/// param name="queryText"
/// returns
public static DataTable GetTable(string connectionString, CommandType queryType, string queryText)
{
Trace.Assert(queryText != null, "QueryExecutor::GetData\nQuery must not be null.");
Trace.Assert(queryText != string.Empty, "QueryExecutor::GetData\nQuery must not be empty.");
Trace.Assert(connectionString != null, "QueryExecutor::GetData\nConnection must not be null.");
Trace.Assert(connectionString != string.Empty, "QueryExecutor::GetData\nConnection must not be empty.");
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand query = connection.CreateCommand();
query.CommandType = queryType;
query.CommandText = queryText;
SqlDataAdapter adapter = new SqlDataAdapter(query.CommandText, connection);
DataTable table = new DataTable();
try
{
adapter.Fill(table);
}
catch (SqlException)
{
ReleaseResources(adapter, connection);
throw;
}
catch (Exception)
{
ReleaseResources(adapter, connection);
throw;
}
return table;
}
private static void ReleaseResources(SqlDataAdapter adapter, SqlConnection connection)
{
adapter.Dispose();
if (connection.State == ConnectionState.Open)
connection.Close();
}
}
I am trying to fully understand the difference between assertions and exceptions. According to readings I have read, I have come to conclusion that assertions are used for errors which should never occur and thus programmers can fix it, and for class invariances. In other words it warns the programmer and helps the programmer know that the code is actually doing what it was intended to do. Exception on the other hand can not be fully avoided but they can be anticipated and gives the opportunity to deal with it somehow during runtime. For example, if the application is trying to read a file from a path provided by the user and the file does not exist, the programmer can not really do anything but throw exception and application will handle it. Then application will tell the user that file does not exist.
My questions now are:
1. In my class above, according to my understanding which I explained above, the programmer should give me a connection string at least, therefore, I am asserting that connection string can not be empty or null. This is an error which should never occur so I am using assertion instead of throwing exception. Is this ok? Wow...I just came up with a thought (funny how when you are asking a question you come up with more questions): What if the caller is reading the connection string from a file and sending it over, now I am not giving the caller the opportunity to handle the error and try again or something. But still the caller should at least verify that the string is not empty or null.
2. Another question is why should I use Trace and not Debug apart from the known fact that Trace is bundled up with release versions but Debug is not.
3. What else is wrong with my style of coding? I know it needs more work to handle TableDirect or simple query.
4. Any other suggestions?
Thanks,
|
|
|
|
|
Have a google for "Design by Contract" and "nContract".
|
|
|
|
|
Thanks for the answer but I am designing based on design by contract. I was hoping someone can answer my questions which were unanswered even after numerous reads. I am still waiting for an answer as that does not help me whatsoever. I have read so many readings based on this topic and seems like not too many people understand it, hence the reason for only 1 reply to my question.
|
|
|
|
|
Ah ok, well I'll put in my 2c on your questions then.
1. Assertions and Exceptions are pretty different concepts. Assertions are a test that you absolutely expect to succeed, and indicates a design/breach of contract error if it fails. A failing assertion needs to perform an action, and this would commonly be throwing an exception (or getting a TraceListener to do something). I'd tend towards throwing an ArgumentException in these cases.
2. Trace is like Debug. Instead of the DEBUG conditional compilation constant, it is dependant on TRACE being defined (which is defined in release mode by default).
3. It won't compile. ReleaseResources can't see adapter or connection due to scoping. Even if you made these static, your method wouldn't be thread-safe.
4. IMO theres no need to "enterprise" up a DAL with all sorts of abstraction if you are doing simple enough things that could be handled by the built-in IDE databinding. If you do need a proper ORM solution, then coding one by hand with sufficient functionality is going to take a long time.
|
|
|
|
|
Hello evrybody.
If I'd like to do a simple application that would collect/track user behavior on the interface (how he is navigating, is he kind of seraching for something,etc) in order to make a short term prediction and help the user by somekind of notification or intelligently update the content of a certain help-topic preview so the user may find help kwikly.. then how can I do such thing in a proper, organizable way ?
What is the proper way to represent the incoming inputs that I am going to reason on..How would be the reasoning sheme for that ?
I'm posing the kestion to see if somebody can direct me at existing solutions based on that, possible techniques that are employed in such case, even links,etc. I will also be happy to open a detailed discussion that would be fruitful to evrybody.
For instance I found this link :
http://www.cwsandbox.org/?page=home[^]
It is about kind of antivirus I think that bases its decisions on the understanding of application behvior. (That's what they say at least). I wonder how the input is organized, how the reasoning is done. Well this is an example that I found it. It proves there are many such cases.
Do you have links for application in same philosophy.
I'm eager to enter this domain, and learn about it.
Thank you in advance.
|
|
|
|
|
Hello everybody,
Months ago, I started having some fun writting a POS (Point Of Sale) system for Restaurants. But as I keep developing it, it got to the point that it is getting very reach in functionalities. So, I decided to go a little further. I decided to make some profit by sellling this software.
I am using VB 2005 Express as my plataform and SQL 2005 as my database ( it can easily be switched from MS SQL 2005 to MS Access 2007).
Since I am developing this POS sytem with VB 2005 express and SQL 2005 express, which can be downloaded for free from Microsoft.com, can I install my POS system on any computer and download the free downloaded SQL 2005 express on those computers? Or in the case of using MS Access 2007, can I just install the the run time files?
Since I am just starting to open myself in the business world, I don't think I will be able to afford to pay for using .NET products. I already have made some budget for purchasing all the physical things for this POS System such as Computers, Label printers, scanners, etc...
Is there any one who has gone through this experience?
I will be glad to hear any comments from anyone of you.
Thanks everyone in advance.
Sincerely,
Tommy4U
aaquino04@hotmail.com
|
|
|
|
|
You need to check the redistribution rights for all libraries you use. SQL Express does come with an installer merge module, so there shouldnt be an issue there.
|
|
|
|
|
Tommy4U wrote: Months ago, I started having some fun writting a POS (Point Of Sale) system
Ok, so far.
Tommy4U wrote: I decided to make some profit by sellling this software.
What? And you think that follows Best Practice for developing production software?
Tommy4U wrote: I am using VB
Ah, ok, that explains it, never mind.
led mike
|
|
|
|
|
Yeah, wow, whatever
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Really, that's how you think it should be done? Interesting
led mike
|
|
|
|
|
led mike wrote: that's how you think it should be done? Interesting
I don't quite follow you, there. I was more of whatever with the OP...
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Paul Conrad wrote: I don't quite follow you, there. I was more of whatever with the OP...
Oops, my bad, I thought you took a shot at me.
led mike
|
|
|
|
|
No worries. I should have been a little more clear.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Tommy4U wrote: I don't think I will be able to afford to pay for using .NET products.
Huh?
Tommy4U wrote: can I install my POS system on any computer and download the free downloaded SQL 2005 express on those computers?
Yes, you can. Don't see why not.
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|
Consider the following simplified case where I store several users at once.
Transaction trans = cn.begintrans
foreach (name in nameArray) {
Person p = new Person(name);
Person.Insert()
}
trans.commit();
I want Person.Insert() to:
- Use the transaction created. (I can't access the transaction object inside the insert() call)
This way, the users are not created when the BL produces an error.
- Still make it reusable in a non transactonal context (such as creating a single user)
I could do it with a using statment using a transactionscope instead, but actually I am wondering how it was done before .NET 2.0?
How can I make the insert method available in transactional and none transactional context without violating three tier principles?
|
|
|
|
|
I would just overload the insert() method so that, if you pass in a transaction object, it uses it.
|
|
|
|
|
That is an option, but ultimately I'm looking for a way to create business logic methods which are reusable in other BL methods in a transactional context without too much hassle. Writing two versions of each method (one with transactional support and one without) seems hard to maintain.
I find it weird that only "recently" (using transactionscope) this is possible without repetitive code.
|
|
|
|
|
You just created a Person object inside the foreach loop after starting a transaction. Why should the person know about the transaction if you are not providing it? Joe is right below, somehow you have to make the person aware of the transaction. In other words, how is that instantiation any different than if you did it before beginning transaction? How is this a three tier architecture?
|
|
|
|
|
Thank you for your reply. The sample I provided serves as an example a for what I'm trying to achieve, I don't consider it "correct".
You are right about the sample not being three tier also. I'm only looking for a way to make a method reusable in both a transactional and a non transactional context (such as insertPerson) without writing two versions of it...if that is possible?
You might write this method just to insert a person into the db and later on you notice that you need to reuse this method in a transaction elsewhere in your application. (for example to insert multiple persons at once) That would basicly mean you need to completely rewrite this method using a transaction for this purpose only.
On the other hand, you can use a transactionscope in .NET which automatically attaches the active transaction to any ADO.NET database call. This way you don't have to rewrite to insertPerson method to be used in transactions.
I'm just wondering what others do in such a situation? Rewrite any method they need to reuse in a transaction with another method signature (e.g. adding a transaction argument like you said.)...that just seems a bit redundant to me.
|
|
|
|
|
Here is what I would do in such a case:
Person class will have a method called Save(). When this method is called it will call the DAL's Save method and pass itself in. DAL will ask the person if it should be inserted or updated--no need to create separate methods for update and insert but you can. If it is to be inserted then DAL should call its own private method and insert the person and do the same if update.
For multiple persons, I would create a PersonCollection class and when Save() is called it will call the PersonCollectionDAL and pass itself in. The PersonCollectionDAL can either ask each person to Save() and pass a transaction over to it. Make this Save() method internal so it is only accessible from DAL Layer not UI Layer. Alternatively, the PersonCollectionDAL can throw all the persons in a DataTable and ask a dataAdapter to insert them. There is no right and wrong way, it is about software craftsmanship.
If you are worried about reusing the insert methods code you mentioned above, then simply make the code a private method and the two public methods (Single and Transactional) can both use it.
Obviously, this is just a suggestion and when you start your implementation you will have other obstacles to overcome.
Finally, although transactions can be used to speed things up for multiple inserts, yet I do not like using them because if one person is not inserted then why should the other ones roll back. Transactions are supposed to be for steps which depend on each other and either all pass or all fail. It is pretty obvious that is not the case here.
|
|
|
|
|
|