|
So what you have created here is:
- a main thread launching a repetitive timer;
- a timer executing "something" on another thread (which happens to be an arbitrary ThreadPool thread);
- as your Run() method takes longer than your timer's interval, two ThreadPool threads are likely to be executing the Run() method in an overlapping way, i.e. a second will start before the first has finished.
No, whatever goes wrong in Run() stays in there. The threadpool thread will survive but not report anything.
Unless (I'm not sure, haven't done this for a while) you set a handler to Application.ThreadException; but then that handler will possibly catch a lot, and your app will in general have a hard time to somehow recover from whatever went wrong.
Here is an alternative that may or may not fit your needs: have a look at BackGroundWorker; this basically is a thread that executes your work; when everything is done, it fires its RunWorkerCompleted event, which (1) runs on the main thread (assuming you created the BGW on the main thread), so you can touch GUI Controls freely from there; and (2) has an Error parameter that holds any uncaught exception that may have occured in (and terminated execution of) the DoWork handler. This way, the exception is there, when you want it, and close to what has caused it.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Thanks for the info about the BackgroundWorker; I hadn't used that before. I had a play, and that works well for running threads and catching exceptions, but as I needed to trigger it from a timer, the issue of bubbling exceptions up past the timer remained. When I tried using the worker's completed event, to retrigger it, this caused a new asynchronous thread to be created, which worried me about the potential for memory leaks and stack overflows; these may not be an issue, but my knowledge isn't good enough to feel comfortable with this yet.
However, I realised that I'd missed an obvious solution. The actual issue I was trying to solve is this:
I have a windows service, which starts a number of threads to poll different resources at various intervals (e.g. one thread monitors a folder on the file system every 30 seconds, another queries a database every hour). These threads are to run in parallel, and also run the handling code for where results are found (ceasing to poll whilst the handler code runs to avoid overloading it). Should an exception occurs in one of these threads, I wanted to ensure that it was reported to the eventlog, so put a try catch around the service call, hoping for it to catch all exceptions.
My solution was to simply change from using a top level exception handler to using a singleton exception handler available to all threads. Each thread then had the standard exception bucket around all of its contents, allowing exceptions to be reported correctly. As I say, this is a solution to a different problem to the one I initially posted, but hopefully this'll help others with similar issues.
Thanks again to Luc for all your assistance.
JB
|
|
|
|
|
Hi Folks,
I'm hoping someone can help me with an issue I've just come across.
I’ve written the demo code below which shows that if I use a timer to schedule events, unless I use a static “sync” variable, a second instance of a class may begin running before the first has completed. Rather than relying on folk remembering and repeating this logic, I’m hoping to put it into an abstract base class, which then calls a method in the subclass to do the processing, safe in the knowledge that another instance of that same class won’t run until this one’s completed. However, if there’s another class deriving from this base class, I’d want instances of the new class to be unaffected by instances of the first subclass (i.e. effectively I want the sync field to be static in the subclass, but available to the base class).
class Program
{
static void Main(string[] args)
{
Base one = new SubClass1();
Base two = new SubClass2();
Timer timer1 = new Timer();
Timer timer2 = new Timer();
timer1.Interval = 3000;
timer1.Elapsed += new ElapsedEventHandler(one.Run);
timer1.Enabled = true;
timer2.Interval = 5000;
timer2.Elapsed += new ElapsedEventHandler(two.Run);
timer2.Enabled = true;System.Threading.Thread.Sleep(20000);
Console.ReadKey();
}
}
abstract class Base
{
private volatile static bool sync = false;
private static object syncroot = string.Empty;
public void Run(object source, ElapsedEventArgs e)
{
if (sync) return;
lock (syncroot)
{
if (sync) return;
sync = true;
}
RunSubClassCode();
sync = false;
}
protected abstract void RunSubClassCode();
}
class SubClass1: Base
{
protected override void RunSubClassCode()
{
Console.WriteLine("1a");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("1b");
}
}
class SubClass2 : Base
{
protected override void RunSubClassCode()
{
Console.WriteLine("2a");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("2b");
}
}
Has anyone come across a similar requirement before, or can you think of any solutions?
Thanks in advance (and again, later),
JB
|
|
|
|
|
you are correct, timer handlers can overlap (unless you use a System.Windows.Forms.Timer which has special characteristics). There are several ways to deal with that, which one you choose may depend on circumstances.
Here is a scheme a like a lot because it is simple:
- ask the timer to tick only once, then call your handler;
- in the handler, when all is done, again arm the timer for a single shot.
The advantage is there is no risk of overlap, and what you are doing in fact is time the idle part of the period, so if the handler takes 3 seconds, and you set the timer to 7 seconds, then your action will run every 10 seconds; if for some reason it takes longer, then all later timer activities will also come later.
The scheme can easily be implemented using the System.Threading.Timer and its Change() method.
If you really want to time the period, i.e. the start point (and not the idle gap), then it is always trickier to get it right under all circumstances. However IMO the fixed gap is what most applications want.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Hey Luc,
that's a great idea; thanks again for your help.
For anyone following this thread (no pun intended), below is an example of the demo code, updated to use this idea (hopefully this agrees with what Luc's described - it definitely works as hoped).
class Example4
{
public static void Test()
{
Base4 one = new SubClass4_1();
Base4 two = new SubClass4_2();
one.Go();
two.Go();
System.Threading.Thread.Sleep(20000);
one.Stop();
two.Stop();
}
}
abstract class Base4
{
DateTime lastRun = DateTime.UtcNow;
Timer timer = new Timer();
public void Go()
{
timer.AutoReset = false;
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = GetInterval();
timer.Enabled = true;
}
public void Stop()
{
timer.Close();
timer.Dispose();
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
lastRun = DateTime.UtcNow;
RunSubClassCode();
Again();
}
private void Again()
{
int interval = GetIntervalAccountForProcessingTime();
try
{
timer.Interval = interval;
timer.Enabled = true;
}
catch (ObjectDisposedException) { }
}
private int GetIntervalAccountForProcessingTime()
{
int interval = GetInterval();
interval -= DateTime.UtcNow.Subtract(lastRun).Milliseconds;
interval = Math.Max(interval, 1);
return interval;
}
protected abstract int GetInterval();
protected abstract void RunSubClassCode();
}
class SubClass4_1 : Base4
{
protected override void RunSubClassCode()
{
Console.WriteLine("1a" + DateTime.UtcNow.ToString("mm ss ffff"));
System.Threading.Thread.Sleep(2000);
Console.WriteLine("1b");
}
protected override int GetInterval()
{
return 3000;
}
}
class SubClass4_2 : Base4
{
protected override void RunSubClassCode()
{
Console.WriteLine("2a" + DateTime.UtcNow.ToString("mm ss ffff"));
System.Threading.Thread.Sleep(2000);
Console.WriteLine("2b");
}
protected override int GetInterval()
{
return 2000;
}
}
Cheers,
JB
|
|
|
|
|
you're welcome.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
hi all, as I titled i'm going to make serial number or an special uniqe number for my project by every exe that I build of it, is there any way to make it dynamically? especialy in msbuild command?
|
|
|
|
|
|
System.Guid.NewGuid.ToString.ToUpper
|
|
|
|
|
Yeah, I know, but the various parts of the serial may have special meaning. Since the OP didn't specify that, I thought I'd demonstrate that *anyone* can use google.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
|
So lets say I have Form1
in Form1 I want to build a reportviewer1 linked to an reportex.rdlc.
I have designed the rdlc and when the code executes it creates the dataset that is returned as dsCount
DataSet dsCount = ConvertDownloadAuditToDataSet(daCountList);
I want reportviewer1 to bind this dsCount to the report.
I know how to build on creating a xsd dataset but when I have an embedded dataset Im not sure how to bind it
|
|
|
|
|
Hi to all,
I want to know,
How to convert => A string of "char" into Text or Bytes information coded using (ISO/IEC 8859-x) character sets according to language used for string of "char" ? Language can be any regional or international.
Thanks & Regards,
Aniket A. Salunkhe
|
|
|
|
|
How about:
Encoding.GetEncoding("iso-8859-1").GetBytes("your-string");
Die Energie der Welt ist konstant. Die Entropie der Welt strebt einem Maximum zu.
|
|
|
|
|
Thank you very much for ur help.
I will try it.
I have to use character code tables ISO/IEC 8859-5 to ISO/IEC 8859-15 & few others (from Annex A.2 of 'Specification for Service Information (SI) in DVB systems' http://www.dvb.org/technology/standards/a038r6.tm1217r17.en300468v1.11.1.pdf[^].
Will it work with it?
Is there any way to identify character code table of a given string?
Thanks & Regards,
Aniket A. Salunkhe
|
|
|
|
|
|
|
1)
public List<string> GetList()
{
List<string> list = new List<string>();
return list;
}
But as per msdn we should not expose the generic list.
How to return a list from a method.
2)
Simillarly I have a method which has dictionary as a return type
How to return a dictionary from a method.
3) In my code I have craeted a dictionary as
Dictionary < int , Some Str> .
Now I need a colletion of keys avaialble in the dictionary.
How to do this.??
Do I need to retrive one by on from dictionary. ??
|
|
|
|
|
Hi,
1.
there is nothing that prevents you from returning a List (or any other collection) like that.
There may be "good practice" or "OO" reasons not to do so under certain circumstances, but it is perfect C#.
2.
see 1.
3.
if you look through the MSDN documentation, more particularly the properties of Dictionary<Tkey, Tvalue>, you will notice it is all there.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
FxCop will recommend using ReadOnlyCollection[^]
I know the language. I've read a book. - _Madmatt
|
|
|
|
|
That seems kind of inefficient. Does that mean there are now two copies of the same data in memory? (Actually, with their crappy sample, the array at the end of the Main() method makes a 3rd copy).
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
modified on Wednesday, June 9, 2010 1:50 PM
|
|
|
|
|
You're not supposed to actually read or use the examples
I know the language. I've read a book. - _Madmatt
|
|
|
|
|
John Simmons / outlaw programmer wrote: Does that mean there are now two copies
No. The way I understand it the ReadOnlyThingy is just a wrapper; it holds a reference to the original collection (and that explains how it tracks the changes to the original collection, see the example), but offers fewer valid operations on that collection. So nothing gets copied.
I haven't used it ever yet, as I see not much point in making the collection read-only, while the items in the collection remain as they were, modifiable at will (except for the silly example that used strings of course).
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I use them quite a lot. Many times I want a collection to be exposed but not have add and remove methods etc as I don't want the collection itself to be modified. I find it very useful!
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
You're probably right, I still have to get used to them...
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|