|
Hi
I am creating a windows service which is using timers. I know I shouldn't use something like DispatcherTimer or Forms.Timer. The problem with other timers(like System.Timers.Timer or System.Threading.Timer) is that its events are raised in background threads. I tried to use the System.Threading.Timer and than use Dispatcher.CurrentDispatcher to marshal the event to the thread that created the timer but this did not work ok. I am asking the following:
Can I use Dispatcher.CurrentDispatcher and Dispatcher.Invoke in windows service app. ?
If not, can somebody direct me in the right way to solve my problem?
Any advice will be appreciated,
Uros
|
|
|
|
|
I use System.Timers.Timer for my Windows Services and I have no trouble. What problem are you having?
|
|
|
|
|
The problem I am having is that the thread that created the timer and started it, is no longer available when the timer's interval elapses. When I created an instance of the CustomTimer - which is just a wrapper around System.Threading.Timer - I save the Dispatcher.CurrentDispatcher in the private field of the CustomTimer. Than I start the timer end wait for its event to get raised(still inside the CustomTimer) and then use the saved Dispatcher to marshal to the thread that created the timer. But in some casses the Thread property of the stored Dispatcher has the state of stoped or WaitSleepJoin. But I am not sure what is the reason for that - maybe one should not use dispatcher in the windows service? I can put the code here if I was not clear.
Thanks for your time,
Uros
|
|
|
|
|
But what's the problem? Why do you care? What are you trying to accomplish? Why would your code care what thread is being used? The only time I've cared about the thread is in WinForms applications, but a Windows Service has no GUI so I don't see what the problem is.
|
|
|
|
|
I am just trying to avoid locking all the resources all over my app., which would be necessary if there would be multiple threads accesing them.
Uros
|
|
|
|
|
But even with a System.Timers.Timer you still really only have one thread active at a time... unless your threads run longer than the timer interval and you wind up with overlapping threads -- but that doesn't really seem like a desireable state so I avoid it.
If you do desire overlapping threads, then I can see where you could have trouble and I have no answers for you. Good luck.
|
|
|
|
|
Have a look at the AsyncOperation and AsyncOperationManager classes. The former has a Post and PostOperationCompleted methods that will call a method on the required thread via the SendOrPostCallback delegate, you could raise your event in that method.
|
|
|
|
|
Thanks for your suggestions. I will try to do some more researh and see if it helps.
Uros
|
|
|
|
|
I was working on the tips offered above, and come across something I do not understand. If I use a System.Threading.Timer in windows service app, and inside it's event handler check the current thread with Thread.ManagedThreadId I get the same value if I check the current thread in the OnStart() method. If I do the same in a Windows forms or WPF app. I get different values. Does anybody knows what is going on?
Thanks in advance,
Uros
|
|
|
|
|
Msdn says, the timer handler method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system. And the threads in the managed thread pool are always background threads. Does this explain why you are not receiving a callback on the UI thread when tried from WinForm or WF applications?
|
|
|
|
|
Hi
I know that timer tick event should execute on the thread from the thread pool. That is expected behavior and that does not bother me. The problem is that this is only true when used in desktop(WPF or Forms) app. If the timer is used in windows service app. it executes on the thread that created the timer instance (at least Thread.CurrentThread.ManagedThreadId implies so and that is what I do not understand.
Thank you for your answer,
Uros
|
|
|
|
|
Hello, currently I am learning to create custom controls. And now here are a few question. A book sugested to use Cache and to use WeakReference class.
When I think of holding properties, I do not know if I should chose a class or a struct. For example: Button. I want to cache to remember all appearance properties. Is it better to use Class or a struct.
Does a class and struct compare by reference?
Is it faster if I call gdi directly instead GDI+?
Is there a better drawing calls instead of GDI+ for a windows form controls?
|
|
|
|
|
Saksida Bojan wrote: When I think of holding properties, I do not know if I should chose a class or a struct. For example: Button. I want to cache to remember all appearance properties. Is it better to use Class or a struct.
Well, it depends. First on how many appearance properties a button has. Second how many buttons and controls
you have. With struct(value) you get a faster access to the properties but you could run in a
StackOverflowException given that the stack memory is relatively small. So it's your decision, cause you know how many properties to hold and how many controls you'll create.
Saksida Bojan wrote: Is it faster if I call gdi directly instead GDI+?
may be faster is some cases but it is more cumbersome.
Saksida Bojan wrote: Is there a better drawing calls instead of GDI+ for a windows form controls?
Not that I know of. Unless you're willing to dive into DX and treat your client area a a DX surface.
|
|
|
|
|
I would choose for a class, because a struct only holds the data of the button and you will have actions too. Besides a class allocates memory for you. Realize that a window quikly has dozens of controls on it, and if for example you want to create a listview you may design the cells as buttons.
A struct would be faster i guess but on the other hand classes are faster as you would expect. Your language has a huge support for classes while with structures you have to do everything yourself.
GDI is faster then GDI+ and is to my opinion not bad at all. GDI+ has some features you can't mimic in GDI (anti-aliassing for example).
|
|
|
|
|
Saksida Bojan wrote: should chose a class or a struct
This is a long running debate and the general consensus seems to be...
Structs should be used for things that hold a specific value that cannot be changed. If it needs to be changed then a new instance is required (immutable). For example, Size . If either the width or height changes then a new instance is assigned to the variable as it's now a different size!
An object such as a Form would always be a class as changing a property would not create a new form.
A class that holds other class/struct instances is normally the best way to go and far easier to deal with.
There are other issues such as recommended size of structs etc. If you do seriously consider using a struct I would do some serious research first and learn about the stack/heap etc...
Saksida Bojan wrote: Does a class and struct compare by reference
Do you mean pass by reference? Structs(being values) are passed by value and classes are passed by reference, although you can use references with structs by using ref / out .
|
|
|
|
|
Hmm, it seems with this i woud prefer to use class
DaveyM69 wrote: Do you mean pass by reference? Structs(being values) are passed by value and classes are passed by reference, although you can use references with structs by using ref / out.
I meant like this:
struct test
{
public Int32 x;
public Int32 y;
}
test t1 = new test();
test t2 = new test();
t1.x = 30;
t2.x = 30;
t1.y = 45;
t2.y = 45;
if (t1 == t2)
DaveyM69 wrote: There are other issues such as recommended size of structs etc. If you do seriously consider using a struct I would do some serious research first and learn about the stack/heap etc...
Do you know where can i find good reading material for this?modified on Saturday, February 13, 2010 3:26 AM
|
|
|
|
|
Welcome to the fustrating world of structs! You have fallen into the first two traps without realising it as we all have done at some point.
test t1 = new test(); Great, you now have a new test instance which has two values, t1.x == 0 and t2.y == 0 .
You now have two issues. Firstly, you change t1 with
t1.x = 30; This should no longer be the same test instance... remember the Size example I gave you earlier?
Also, as x (and y) are public, anyone can change them, which again should creade new instances.
The solution to this is to only set the fields in a constructor, make them private and expose them as readonly properties.
To test for equality using the == operator, it needs overloading and the individual values checked. This also requires overloading != and overriding Equals and GetHashCode .
So, even for a simple struct that holds two ints, you end up with something like this (untested!).
public struct TestStruct : IEquatable<TestStruct>
{
public static readonly TestStruct Empty = new TestStruct();
private int x;
private int y;
public TestStruct(int x, int y)
{
this.x = x;
this.y = y;
}
public static bool operator ==(TestStruct a, TestStruct b)
{
return (a.x == b.x) && (a.y == b.y);
}
public static bool operator !=(TestStruct a, TestStruct b)
{
return !(a == b);
}
public int X
{
get { return x; }
}
public int Y
{
get { return y; }
}
public override bool Equals(object obj)
{
if (obj is TestStruct)
return Equals((TestStruct)obj);
return false;
}
public bool Equals(TestStruct other)
{
return other == this;
}
public override int GetHashCode()
{
return x ^ y;
}
public override string ToString()
{
return string.Format("X={0}, Y={1}", x, y);
}
}
|
|
|
|
|
Now i understand it. And that is to use class not struct.
Thank you for your time
|
|
|
|
|
Saksida Bojan wrote: Do you know where can i find good reading material for this
I'm no authority on the under the covers stuff, do some googling and you will find plenty of results. Hopefully someone more knowledgeable about this stuff will see this and post.
|
|
|
|
|
Now :
-abstract classA
-inherited classB with interfaceX
-inherited classC with interfaceX
-inherited classD with interfaceX
-sealed classX that calls interfaceX
But a lot of the commands in interfaceX , could be directly handled by the base class.
Only some of the commands in interfaceX , are specific enough to be handled by the inherited class.
I think i want :
-abstract classA with interfaceX
-inherited classB overides interfaceX.commandC
-inherited classC overides interfaceX.commandC
-inherited classD overides interfaceX.commandC
-sealed classX that calls interfaceX
Am i right , or am i missing something ??Jarno Burger
Video Jockey
|
|
|
|
|
If you want to use second design, abstract class needs to have virtual method of commandC.
example:
public interface ITest
{
void Test();
}
public class T1 : ITest
{
public T1(){}
public virtual void Test()
{
MessageBox.Show("From parent");
}
}
public class T2 : T1
{
public T2(){}
public override void Test()
{
MessageBox.Show("And I am parent's baby");
}
}
T1 t1 = new T1();
T2 t2 = new T2();
ITest tt1 = (ITest)t1;
ITest tt2 = (ITest)t2;
t1.Test();
t2.Test();
tt1.Test();
tt2.Test();
In the end both design method woud work. In your case i would chose the second. But it is up to you to chose
|
|
|
|
|
I think that would be the way to go. I would also declare commandC in classA as abstract and force an override.
Alternative:
If you have a lot of commands that would have to overridden, you would want to use interface inheritance.
-interfaceX would not have the definition for commandC.
-You could then create interfaceY that inherits interfaceX and define commandC.
-Classes B-D would inherit classA and implement interfaceY.
-In classX you would call interfaceY.
The only problem with your method: If you later change the definition of interfaceX you would have to change all the classes (classA would have to be modified even though there is no real change). This would also be true if you wanted to add a method. It all depends on the size of your classes/interface and how often they will change.
|
|
|
|
|
thanx , you both cleaned my perspective with those abstract concepts ! Jarno Burger
Video Jockey
|
|
|
|
|
i want to write a program.
i want to enter a number in between 4000 and 8000 and this number should contain the digit "2" in any place.eg:4002,4213,5002
please provide the complete coding.As iam a beginner,i consulted many people, but didn't get the answer.
|
|
|
|
|
ajay 2010 wrote: i consulted many people
Exactly how many times are you going to ask the same question without even bothering to try and do it yourself?Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
Individuality is fine, as long as we do it together - F. Burns
Help humanity, join the CodeProject grid computing team here
|
|
|
|