|
That would be the one, I knew I shouldn't have posted so late!
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
... and just think, there was a time when I was richer than Bill Gates.
This feat is not that impressive in that I am a bit older than him and was making a living in the real world when he was a poor student.
I'm retired. There's a nap for that...
- Harvey
|
|
|
|
|
As the child of millionaires, he was never a poor student.
|
|
|
|
|
I think that you are right that his college education was paid for but he was still a poor student (in the money sense).
He went into a bit of debt while founding Microsoft at the same time that I was solvent.
I'm retired. There's a nap for that...
- Harvey
|
|
|
|
|
Quote: At least he actually made his wealth from building something. Unlike a lot of others.
Nope. He made a lot of money from Windows certainly but like all the super-wealthy he made the vast majority of his present fortune simply from having money. Nobody reaches that level of wealth by the sweat of their brow. It is investment managers and accountants and tax advisors who made his wealth. All Gates does these days is sit back and watch it roll in.
|
|
|
|
|
He started off his wealth from Microsoft efforts. As the company has matured, most of his wealth comes from stock, which has a minor correlation with accomplishments of the company.
I'm retired. There's a nap for that...
- Harvey
|
|
|
|
|
This is NOT a programming question. I just figured that since a few of you are programmers, you might be interested in what I'm doing.
I made a preliminary test run of my Sql Express Agent Service code. This is exercising the Timer agents (agents that run at a specified interval (or on a certain day/date). Multiple agent tasks can be implemented via app.config entries. The intervals for the three tasks represented below are set at 1 minute (Interval Task 01), two minutes (Interval Task 2), and 3 minutes (Interval Task 03).
12:11 AgentTimerTest01 - started module
12:11 Interval Task 01 - Tick
12:11 Interval Task 02 - Tick
12:11 Interval Task 03 - Tick
The thread 0x14edc has exited with code 259 (0x103).
12:12 Interval Task 01 - Tick
The thread 0x1564c has exited with code 259 (0x103).
12:13 Interval Task 01 - Tick
12:13 Interval Task 02 - Tick
The thread 0x14ea8 has exited with code 259 (0x103).
12:14 Interval Task 01 - Tick
12:14 Interval Task 03 - Tick
The thread 0x15768 has exited with code 259 (0x103).
12:15 Interval Task 01 - Tick
12:15 Interval Task 02 - Tick
The thread 0x157e0 has exited with code 259 (0x103).
12:16 Interval Task 01 - Tick
The thread 0x15518 has exited with code 0 (0x0).
The thread 0x15704 has exited with code 259 (0x103).
The thread 0x28b0 has exited with code 259 (0x103).
12:17 Interval Task 01 - Tick
12:17 Interval Task 02 - Tick
12:17 Interval Task 03 - Tick
Each add-in module will be hot pluggable, and will be reconfigurable via its config file, as well as reconfigurable tasks - while the service is running. Currently there are three supported agent classes:
Timer - time-based agents (uses my Schedule Future Dates article)
FileSystem - watches the specified folder for the specified file mask (uses my FileWatcherEx article)
WebRequest - derived from the Timer agent, and performs a web request on the configured URL at the specified time/date interval
One or more of each type of agent can be configured for each plug-in module.
I've restarted this project from scratch five times so far, and I think I've finally got a solid start. The absolute biggest hurdle has been abstracting behavior to lessen the amount of work that's required to write for new modules.
Here's the "do work" code:
protected void DoWork(AgentTask taskObj)
{
this.DoAgentWork();
DateTime targetTime = DateTime.Now;
do
{
targetTime = targetTime.GetFutureDateTime(this.Config.Schedule, this.Config.TimeOfDay, this.Config.DayOfWeek, this.Config.Ordinal, this.Config.Month);
CancellationTokenSource tokenSource = new CancellationTokenSource(targetTime - DateTime.Now);
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
if (!taskObj.CancelToken.IsCancellationRequested)
{
this.DoAgentWork();
}
} while (!taskObj.CancelToken.IsCancellationRequested);
}
private void DoAgentWork()
{
Debug.WriteLine("{0} {1} - Tick", DateTime.Now.ToString("hh:mm"), this.Config.Name);
}
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
modified 3-Mar-15 14:06pm.
|
|
|
|
|
Epic fail. No fart jokes or pictures of naked elephants.
Seriously, put this is your blog or something and keep us updated. I love this kind of stuff.
|
|
|
|
|
Slacker007 wrote: naked elephants. Uh, this is the Lounge. Take it to the soapbox.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
eh, don't be a sunshine.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
TheGreatAndPowerfulOz wrote: don't be a sunshine. Why don't you put your comment where the sun don't shine.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Well, elephant that why don't you?
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
John Simmons / outlaw programmer wrote:
this.DoAgentWork();
do
{
this.DoAgentWork();
if (!taskObj.CancelToken.IsCancellationRequested)
{
this.DoAgentWork();
}
} while (!taskObj.CancelToken.IsCancellationRequested); Is, IMHO, better. Removed <snip>'d code for clarity.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
Actually, this would be even better:
this.DoAgentWork(taskObj.CancelToken);
(and I already made a not in my code to do that).
That way a long-running process inside DoAgentWork could watch the status of the token.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
This bit looks wrong to me:
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
You're starting a task on a background thread which blocks until either the AgentTask is cancelled or the target time is reached, but then you're blocking the current thread waiting for that task to complete.
I suspect there's a better way of doing it - but this isn't the right forum to discuss it.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
The waiter has a cancellation token and waits until either the timeout or a cancelation token is activated. Beyond that, the thread needs to wait until the waiter is done before continuing, and it doesn't block any other running agent tasks. I don't understand how that's incorrect.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
You're pushing work off onto a background thread, and then blocking the current thread waiting for the work to finish. You could almost certainly move the work out onto the current thread without changing the behaviour:
Task waiter = new Task(() =>
{
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
}, tokenSource.Token);
waiter.Start();
waiter.Wait();
SpinWait.SpinUntil( () => tokenSource.IsCancellationRequested || taskObj.CancelToken.IsCancellationRequested);
There might be a way to make it work without blocking the current thread, using async / await .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
But I WANT to block the thread (and it's even still responsiove to the cancel token). It's simply waiting for a time span to go by before doing the work at the bottom of the loop.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Yes, you want to block the current thread; but your code is blocking TWO threads!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Good point.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader.-John Q. Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering.-Wernher von Braun Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.-Albert Einstein
|
|
|
|
|
Doing it your way makes it run forever. I still need it to cancel itself after the timeout has expired.
I think I see what you're saying - gotta run it that way to see what it does.
Real work is yanking on my sleeve, so I have to pick this up in an hour or two.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
John Simmons / outlaw programmer wrote: Sql Express Agent
Get a couple certificates and now you are an expert!
Mongo: Mongo only pawn... in game of life.
|
|
|
|
|
|
Add "Undo Pending Changes" to the code window tab's context menu.
Now I won't have to search all over the solution to find the file because I accidentally hit the keyboard.
If it's not broken, fix it until it is
|
|
|
|
|