|
Be happy that you don't know anything about it! It's old , a pain and a mess to work with.
My tip is: Ignore it and find better bus system to work with. Preferred a object oriented instead of register based.
|
|
|
|
|
Did you know that Code Project has a whole series of articles on a wide variety of topics? Funnily enough, someone already wrote an article about Modbus - you can find it here[^].
|
|
|
|
|
I'm not sure what I've gone wrong. It works ok in same namespace but not in different namespace. I use the dll calling to pass the enum value.
The compiler spat out 2 errors:
Error 1: The best overloaded method match for 'junkie.NewClass1.TestMethod(junkie.Output_State)' has some invalid arguments
Error 2: Argument 1: cannot convert from 'junk.Output_State' to 'junkie.Output_State'
sample code that I've written:
using junkie;
namespace junk
{
public enum Output_State
{
OFF,
ON,
Dont_Care,
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
ClassTwo testClassTwo = new ClassTwo();
testClassTwo.TestMethod(Output_State.Dont_Care);
}
}
public class ClassTwo
{
junkie.NewClass1 testClassThree = new junkie.NewClass1();
public void TestMethod(Output_State output)
{
testClassThree.TestMethod(output);
}
}
}
in a new class file:
namespace junkie
{
public enum Output_State
{
OFF,
ON,
Dont_Care,
}
class NewClass1
{
public void TestMethod(Output_State output)
{
switch (output)
{
case Output_State.ON: MessageBox.Show("ON"); break;
case Output_State.OFF: MessageBox.Show("OFF"); break;
case Output_State.Dont_Care: MessageBox.Show("Don't Care"); break;
default: MessageBox.Show("HUH?"); break;
}
}
}
}
|
|
|
|
|
The reason you are having a problem is because these aren't the same enums. By that, I mean that you have actually declared two enums here - the fact that they have the same names means nothing. What you need to do is drop the enum from the junkie namespace, and then add a simple using junk; statement to junkie. It will look like this:
namespace junkie
{
using junk;
public class NewClass1
{
public void TestMethod(Output_State output)
{
}
}
} The using statement means that the junk.Output_State enumeration is used.
|
|
|
|
|
that what you suggested is good... but I think I would use the better way is to drop the enum in 'junk' namespace and reads as follows (no change in 2nd class file):
using junkie;
namespace junk
{
public partial class Form1 : Form
{
SerialPort _port;
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
ClassTwo testClassTwo = new ClassTwo();
testClassTwo.TestMethod(junkie.Output_State.Dont_Care);
}
}
public class ClassTwo
{
junkie.NewClass1 testClassThree = new junkie.NewClass1();
public void TestMethod(junkie.Output_State output)
{
testClassThree.TestMethod(output);
}
}
}
<pre>
Thanks for a big help... I've learned something new.
modified 23-Aug-12 8:59am.
|
|
|
|
|
junk.Output_State and junkie.Output_State are two different types, even though they appear identical in all other respects.
|
|
|
|
|
If these enums are not going to change over time and they are similar, I suggest you to have it in a common namespace and access it in both places.
like,
namespace Common
{
public enum Output_State
{
OFF,
ON,
Dont_Care,
}
}
namespace junk
{
using junkie;
using Common;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
ClassTwo testClassTwo = new ClassTwo();
testClassTwo.TestMethod(Output_State.Dont_Care);
}
}
public class ClassTwo
{
junkie.NewClass1 testClassThree = new junkie.NewClass1();
public void TestMethod(Output_State output)
{
testClassThree.TestMethod(output);
}
}
}
namespace junkie
{
using Common;
class NewClass1
{
public void TestMethod(Output_State output)
{
switch (output)
{
case Output_State.ON: MessageBox.Show("ON"); break;
case Output_State.OFF: MessageBox.Show("OFF"); break;
case Output_State.Dont_Care: MessageBox.Show("Don't Care"); break;
default: MessageBox.Show("HUH?"); break;
}
}
}
}
|
|
|
|
|
Hmm... I like the suggestion you've made. I'll look into that in the future revision. Thanks!
|
|
|
|
|
I have a Windows service which I sometimes cannot properly stop. Sometimes I get "Error 1053". Error 1053 is an error when a time-out has elapsed for starting and stopping services. Simple terms: It takes to long to start or stop a service.
By trial and error I have found out, on my computer, that it takes about 2 minutes and 10 seconds for the error to occur. 2 min and 5 sec is fine.
When I'm trying to stop the service the service might be in a process to read and export data. This process maybe takes some seconds or maybe a minutes to complete. I can never tell how long time the procedure takes.
I would like to finish the process and then stop the service. But since it can take up to minutes to finish the process I'm sure I'll spend to much time in the OnStop() method.
I have tried the Service.RequestAdditionalTime() method to give the service more time to wait so my process can finish. But "Error 1053" still occur for me.
I have tried with 10 ms and 1000ms. No success!
My code is basically this, very simplified:
using System;
using System.ServiceProcess;
using System.Threading;
public class Application
{
public bool running = true;
public bool terminated = false;
public void MainLoop()
{
while(running)
{
ReadData();
ExportData();
}
terminated = true;
}
private void ReadData()
{
}
private void ExportData()
{
}
}
public partial class Service: ServiceBase
{
Application application;
public Service()
{
InitializeComponent();
}
public OnStart()
{
this.application = new Application();
Thread mainLoopThread = new Thread(application.MainLoop);
mainLoopThread.Start();
}
public OnStop()
{
applicaiton.running = false;
while(application.terminated == false)
{
this.RequestAdditionalTime(1000);
}
}
}
Let's assume the Application.ReadData() method takes 3 minutes to complete. Much longer than the OnStop() method is allowed to run.
How can make OnStop() method accept longer time to wait?
|
|
|
|
|
Mc_Topaz wrote: How can make OnStop() method accept longer time to wait?
AFAIK, controlled by Windows, not by code.
Why not simply use a normal executable with a (background) thread? One that polls whether the user cancelled the action?
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Can you describe this "normal executable" more precisely?
Should it be a normal console application that the windows service starts and stops?
|
|
|
|
|
According to the KISS principle, you'd always use a console, until required to do otherwise. Services are a special kind of app, and unless you need to do processing without a user interacting, you often don't need it.
The poster below is right; your thread isn't stopping. Hence the suggestion to use a background-thread and check for a "cancel" indication in the loop. Having it as a console-app makes debugging easier, and you wouldn't have to worry about where you are and aren't allowed to write on the filesystem.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
You need to allow ReadData to be interruptible. Stopping services is something which is supposed to happen quickly, so the user can shut down or restart his machine in a timely fashion.
|
|
|
|
|
You have your point.
But still, with that solution I might miss things to read in the ReadData() method.
|
|
|
|
|
Mc_Topaz wrote: I might miss things to read in the ReadData() method.
But do you care?
|
|
|
|
|
No, actually I don't care *lol*
It's up to my customer if he want to stop the service and maybe lose data.
|
|
|
|
|
The point is that when your service is asked to stop, you shouldn't be concerned about what the in-progress actions of the service are. Your job is to shut down cleanly as soon as you can. Next time the service is started, you can resume or restart any actions that were in progress (obviously, resume is better, but takes more work to make it function correctly).
|
|
|
|
|
Windows expects a service to stop in a certain amount of time. I thought it was only 30 seconds.
If not then windows reports an error however it does not stop anything.
So you have several distinct problems.
1. Do you really want the user to wait 3 minutes for the service to stop? What if your process starts taking longer and it takes 15 minutes?
2. If you do want your users to wait that long then you must educate them. Because some of them will figure out that they can kill the service.
3. What if your secondary process becomes blocked and never returns? What does the user do then?
4. Documentation would suggest that RequestAdditionalTime should work however I doubt it will work like you have it set up. You can't just blast it endlessly. I wouldn't be surprised if your code just makes it hit a limit far before your code is done and so windows just ignores it.
If RequestAdditionalTime doesn't work then there is at least one other API which you can find by googling on the topic. You might or might not need interop to access it.
To use RequestAdditionalTime in a reasonable way I would do it as follows.
1. Set up a loop which sleeps for a small interval and checks for completion of the process. If complete exit. This runs for 20 seconds.
2. Set up a loop which sleeps for a small interval of time, say 5 seconds, checks for process completion and if not complete call RequestAdditionalTime with 5000, then loop again. If the process finishes then exit. This runs for a configurable amount of time. If that amount of time is exceeded then exit regardless of whether process is complete or not.
Note that via experimentation I have found that one MUST call Exit() to insure that all threads are stopped when a service exits.
|
|
|
|
|
can you use Thread.Sleep(40000); onstop Event
|
|
|
|
|
Dear Community
I have written several control-related classes (eg, Symbol, Curve) that store drawing-related information such as line colour, dash style, line thickness, &c in a System.Drawing.Pen property. It is very convenient in code, but in the designer property grid it does not expand and is greyed out.
I have carried out some research and found what is to be done when it is a custom class I want to expand in the property grid ( http://msdn.microsoft.com/en-us/library/aa302326.aspx[^] ), but it is of no help to me as what I use is a built-in type, not my own class.
First of all, do you think it is worth some further ado, or is what I do (simply exposing the System.Drawing.Pen with which I draw the object) considered bad practice?
If it is bad practice, what would you suggest as an elegant solution?
If it is not, how can I make it expand properly in the property grid and be editable?
Thank you very much for your assistance.
Yours faithfully
Tethered Sun
|
|
|
|
|
AFAIK, there is no property-editor for the pen-class; it consists of a brush, a color, a dashstyle and more. Which of the properties of the pen do you want to expose in the PropertyGrid ? Perhaps you could bind those, as opposed to the entire class.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Thank you for your response.
Basically exposing all properties of Pen makes sense for me, as they all control the appearance of the line I should like to draw.
When I started, I was just interested in colour and width. Then came the need for controlling dash style, and exposing the whole Pen allowed me to accomplish that without adding a single line. I do find this convenient, apart from its behaviour in the property browser.
|
|
|
|
|
In that case, you'd prolly have to write your own property-editor. There's a short example here[^]. Benefit is that you can create it exactly as you need it, include all the properties you'd want.
Play a day with the code, it looks harder than it is
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Thank you very much!
I'll do that. Thanks again.
|
|
|
|
|
You're welcome
|
|
|
|