|
I am looking for a good design at how to implement a Windows service which would need to run multiple jobs where each job will talk to different external systems. Like say, When i start the windows service, it should do the following
1. Invoke a process, which would connect to an external system A and perform its job.
2. Invoke another process which would connect to an external system B and perform its job.
3. Invoke another process which would connect to an external system C and perform its job.
What i was mostly interested is, when we start the windows service, if we have any connection exception to any one of the external system, the windows service should still start and connect to the remaining external systems which it was able to connect. In essence, the entire windows service should not go down if the service was not able to connect to any of the external system.
In my current implementation, whenever the windows service starts, i am invoking three different threads for the three external systems and if anyone of them fails , the windows service will not start.
Any inputs to implement the above solution in a better way is appreciated.
|
|
|
|
|
You said it yourself. The service starts and launches a PROCESS. A thread is not a process. It's a thread of execution doing some work.
Your service would be launching processes, separate .EXE's, that stand on their own and do work on their own.
In your current implementation, you're not supposed to be launching threads to do work from inside the code that starts the service. Also, it seems as though each worker is dependent on the same database objects (connection at least), meaning if one fails, they all fail. WRONG! Your design is flawed. Each worker should have it's own SQL support right down to its own SQL connection objects and possibly even connection string. That way they are completely independent of each other.
I've done something similar, but I went with a plug-in system where each plug-in (.dll) is loadable by the service when needed and is unloaded when not. This allows me to have each plug-in talk to the service for logging and exception handling purposes and also allows me to swap out .dll's without shutting down the entire service.
No, I'm not sharing the code with anyone. I put way too much work into it to give it away for free.
Hints: I used Log4Net, a custom log forwarder to cross AppDomain boundries, TopShelf, a heavily modified version of the Simple Plugins Framework from a SourceForge project, a custom scheduling engine and a new configuration module.
|
|
|
|
|
I need to wrap a stored procedure within the transaction and this stored procedure spans through 6 to 7 tables. So, there are high chances of dead lock in our application. What is the best approach to handle transaction here?
|
|
|
|
|
Member 10661997 wrote: What is the best approach to handle transaction here? Reading[^].
The transaction will be (and should be) rolled back, see here[^].
Member 10661997 wrote: So, there are high chances of dead lock in our application. Only if you update the data a lot.
In that case, it may be more interesting to find out whether those tuples would have fields that are updated more often than the others; a new table with a 1-1 relation might prevent the need to lock the record if it only contains fields that are rarely updated.
--edit
This is the C# forum, and the question is more related to "databases". You might get a better answer there.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I have been using a common tool that will create me a Timeline but i am having trouble understanding how to change how to timings work.
At the moment when i load my project up it looks like this:
http://i.imgur.com/Wp5LFdA.png
I want to be able to say that the EndTime of the Timelines are the length of a video i have uploaded e.g.
double length = axWindowsMediaPlayer.Length
Then I want the lines on the timeline to be split down every 5 minutes.
I am really struggling with this and would be great if someone could help further.
|
|
|
|
|
You have to show us some code. We can't guess how the timeline works, what code you have, anything.
This space for rent
|
|
|
|
|
Since you've indicated this is WPF, the Silverlight / WPF[^] forum might be abetter place to ask.
"Fairy tales do not tell children the dragons exist. Children already know that dragons exist. Fairy tales tell children the dragons can be killed."
- G.K. Chesterton
|
|
|
|
|
Hi,
I am trying to send SMS using Jamaa SMPP but it's making me crazy! I keep getting:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 193.188.124.116:2775
The IP, user name, password are correct and I got it from my provider.
How can I fix it please? here is my code:
SmppClient client = new SmppClient();
SmppConnectionProperties properties = new SmppConnectionProperties();
TextMessage msg = new TextMessage();
client = new SmppClient();
properties = client.Properties;
properties.SystemID = txtUserID.Text;
properties.Password = txtPassword.Text;
properties.Port = Convert.ToInt32(txtPort.Text);
properties.Host = txtIP.Text;
properties.SystemType = txtType.Text;
properties.DefaultServiceType = ServiceType.DEFAULT;
client.AutoReconnectDelay = 3000;
client.KeepAliveInterval = 30000;
client.Start();
if (client.ConnectionState != SmppConnectionState.Connected) client.ForceConnect(5000);
msg = new TextMessage();
msg.DestinationAddress = txtMobile.Text;
msg.SourceAddress = txtSenderID.Text;
msg.Text = txtMessage.Text;
msg.RegisterDeliveryNotification = true;
client.SendMessage(msg, 1000);
client.Shutdown();
Thanks,
Jassim[^]
Technology News @ www.JassimRahma.com
|
|
|
|
|
Jassim Rahma wrote: The IP, user name, password are correct and I got it from my provider.
Is the port (2775 ) correct?
It's not a standard port, so is there a firewall between the two computers which need to be configured to allow traffic through on that port?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = global::System.Data.CommandType.Text;
cmd.CommandText = "SELECT * FROM Table1 WHERE RFID = '" + textBox1.Text + "'";
cmd.Connection = myCon;
this.table1TableAdapter.Adapter.SelectCommand = cmd;
this.table1TableAdapter.Adapter.Fill(mdb11DataSet.Table1);
dgvConnect = new NominalRollDBConnection();
conString = Properties.Settings.Default.NominalRollCS;
dgvConnect.connection_string = conString;
dgvConnect.Sql1 = "SELECT * FROM NominalRoll WHERE RFID = '" + textBox1.Text + "'";
ds = dgvConnect.GetConnection1;
this.nominalRollTableAdapter.Fill(nominalRollDataSet.NominalRoll);
class NominalRollDBConnection
{
private string strCon;
private string sql_string1;
System.Data.SqlClient.SqlDataAdapter da_1;
public string Sql1
{
set { sql_string1 = value; }
}
public string connection_string
{
set { strCon = value; }
}
public System.Data.DataSet GetConnection1
{
get
{ return MyDataSet1(); }
}
private System.Data.DataSet MyDataSet1()
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(strCon);
con.Open();
da_1 = new System.Data.SqlClient.SqlDataAdapter(sql_string1, con);
System.Data.DataSet dat_set = new System.Data.DataSet();
System.Data.DataTable dat_table = new System.Data.DataTable();
da_1.Fill(dat_set, "Table_Data_1");
con.Close();
return dat_set;
}
I have a difference in output when using datagridview to display my data tables.
For the code above it outputs as per my query.
However for the second code it outputs the entire data table, can anyone please explain ?
Thank you
edit: I have binded the datagridview using the GUI for the code above and below to respective datasources
modified 30-Nov-15 21:45pm.
|
|
|
|
|
Use the debugger to see exactly what command you are passing through, then look directly at the DB - without the data we would just be guessing what is in your two tables and text boxes.
But do yourself a favour: Do not concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Use Parametrized queries instead.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
OriginalGriff wrote: It leaves you wide open to accidental I'd love to hear the excuse for accidentally dropping the user table, Little Bobby Tables is not an accident!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Yeah, I know what you mean. But I like to presume Innocence instead of Guilt (unlike our current legal system)
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Hi, thanks for your help, I have tried using the debugger and it appears that for the code below it is not using my SQL query statements.
I have tried moving the query statements into the NominalRollDBConnection class and declaring the statements directly on my form part of the program but it still does not work.
I will try to resolve this via declaring all the SQL connections manually rather than use a separate class as now, am I headed the right way if I were to do this ?
Sorry if it looks as though as I am doing "crazy" things with the declarations. This is due to me being a total beginner to C# and my only prior lessons is very basic console applications using C++.
|
|
|
|
|
Member 12040781 wrote: cmd.CommandType = global::System.Data.CommandType.Text;
I know it's different to your original query but why are you setting the command type with a global reference to what is effectively an enum?
Every day, thousands of innocent plants are killed by vegetarians.
Help end the violence EAT BACON
|
|
|
|
|
..and why set it explicitly to its default value?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Sorry, I did not have prior knowledge to enums, this is my first time using C#. From the example that I have on hand they're doing the declarations this way.
I will try to declare an enum class for the cmd object and see whether it will work.
|
|
|
|
|
Hello,when i start thread to plot in chart,but form is lose control, looks like thread is not in use.
private void button1_Click(object sender, EventArgs e)
{
Thread th=new Thread(new ThreadStart(fun1));
th.Start();
}
void fun1()
{
base.Invoke((MethodInvoker)delegate{
Series series1 = new Series();
for (int i = 0; i < 300; i++)
{
series1.Points.Add(new DataPoint(i, i));
Thread.Sleep(1000);
}
chart1.Series.Add(series1);
});
}
|
|
|
|
|
Ohm the thread works. The problem is that the code you're Invoking is being executed on the UI thread, not the thread you launched, because, well, THAT'S WHAT INVOKE DOES! And then you put the UI thread to sleep for a second. Once the Sleep is done and the delegate is done running, THEN you UI thread can get back to processing the message pump, like responding to WM_PAINT messages to repaint your window if needed.
You cannot touch a UI control properties or methods from anything other than the UI thread. You can create a new Series object and populate it with data in the background thread and THEN make the assignment to the chart object in delegated code. You're doing everything in the delegate, on the UI thread.
|
|
|
|
|
Hello, I have simply tried to create a static field on a class that will work like a counter for the instances ,but where I am trying to print the counter value is always on 0;
class Program
{
public static int Counter;
public Program()
{
Counter++;
}
static void Main(string[] args)
{
Program b;
Program c;
Console.WriteLine("{0}", Counter);
}
}
what is the problem ?
B.Is there a way to create a static var that is not field of the class and will work inside the class constructor (same idea as counter for the instances) ?
Thanks !
|
|
|
|
|
If you're talking about how many instances of your application are running, that's not going to work. You have to count the number of processes that are running using the process name of your application and the Process class.
If you're talking about how many instances of a class you have inside a single instance of a running application, that code may work.
|
|
|
|
|
I am talking just about the instances of the class,as in the answer below thanks !
|
|
|
|
|
There is no problem - the code is doing exactly what you've told it to!
You increment the Counter variable each time you create a new instance of the Program class. However, you never create an instance of the Program class - you just declare two variables which could potentially hold an instance of that class in the future.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
The problem is that in this case, you aren't creating any instances of your class, just the variables to hold instances. If Program was a struct rather than a class, then
Program b;
Program c;
would create instances - but they still wouldn't increment your counter, because value type constructions aren't implicitly called.
Try this:
Program b = new Program();
Program c = new Program();
And your counter will be incremented as you expect because you are creating instances.
A variable isn't the same as an instance: think of a variable as a "parking space" - it can hold any Car object, but you can't drive the space down to the shops! The parking space is the variable, the instance is the actual Car it holds.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|