For loop cause IndexOutOfBoundException - c#

I faced a curious situation today when I developing windows service.
I have a MonitorOutputFile inside which I implement FileSystemWatcher in the method MonitorOutputFile.
When I wrote the code as below
foreach (string filePath in filePathValue)
{new Thread(() => monitorController.MonitorOutputFile(filePath, pollRetryInterval, fileWaitTime)).Start();}
-->It works well in the OnStart();
However, when I use
for(int i=0;i<filePathValue.Length;i++)
{
new Thread(() => monitorController.MonitorOutputFile(filePathValue[i], pollRetryInterval, fileWaitTime)).Start();
}
-->This throw IndexOutOfBoundException in the OnStart() method.
I tot that is my problem, so I do a output
for(int i=0;i<filePathValue.Length;i++)
{
EventLog.WriteEntry(SourceName, filePathValue[i], EventLogEntryType.Information, 58987);
}
-->This able to output the correct output of the filePathValue[i].
Unlike Thread causing IndexOutOfBoundException
which was expecting a return value, my windows service does not wait for any return value. Does this two having the similarity?
Can somebody tell me why is this happening? Hope that somebody able to share some light with me on this curious case.

Your lambda captures the last i value, which is filePathValue.Length. Try this:
for (int i = 0; i < filePathValue.Length; i++)
{
int i1 = i;
new Thread(
() => monitorController.MonitorOutputFile(
filePathValue[i1], pollRetryInterval, fileWaitTime)).Start();
}

This is a common issue. You're capturing the loop counter in your anonymous method, so all the threads, once they execute, are likely to read the same (final) value of i. Instead, you should assign i to a variable declared within the loop body, ensuring that each thread reads its own copy.
for(int i=0;i<filePathValue.Length;i++)
{
int iInner = i;
new Thread(() => monitorController.MonitorOutputFile(filePathValue[iInner], pollRetryInterval, fileWaitTime)).Start();
}

When variable i is send as parameter to a lambda expression. When the lamba expression is executed this in the thread, your for loop will be already done. so you can create a inner variable to hold the value. I think you can try the below code, it should be work
for(int i=0;i<filePathValue.Length;i++)
{
var fileValue =filePathValue[i];
new Thread(() => monitorController.MonitorOutputFile(fileValue, pollRetryInterval, fileWaitTime)).Start();
}

Related

c# - create thread in for loop (arguement out of range exception)

I don't know how to describe this problem precisely. Let's look at my code.
for (int i = 0; i < myMT.Keys[key_indexer].Count; i++)
{
threads.Add(new Thread(
() =>
{
sounds[myMT.Keys[key_indexer][i]].PlayLooping();
}
));
threads[threads.Count - 1].Start();
}
Note: sounds is a list of SoundPlayers
The initialization of threads and myMT:
List<Thread> threads = null;
MusicTransfer myMT=null;
and in the constructor:
threads = new List<Thread>();
myMT = new MusicTransfer(bubblePanel);
The variable Keys in myMT is with type of List<List<int>>. It is initialized with the same way of myMT and threads. Imagine a matrix, the outer list is a list of rows and the inner one is for each cell.
When I run the program, I set myMT.Keys[key_indexer].Count to 1. So, normally, the for loop should stop when i reach 1.
However, it throws an exception of ArgumentOutOfRange at the line of sounds[myMT.Keys[key_indexer][i]].PlayLooping(). So, I used debugger to check the value of each variable.
What I found are:
If I use "step over" check step by step, which means time is consumed quite much after the new thread runs, for loop will stop when i reaches 1, which is the way it should be.
If I click "continue" after the breakpoint triggered, the for loop is still processing after i equals 1.
the break point should always be set at the line of threads.Add(new Thread(. If it is set at the line of sounds[myMT.Keys[key_indexer][i]].PlayLooping();, the exception will be triggered even after "step over"
I guess the problem is about thread, but have no idea how to solve it.
Thanks for any help!
There is so many things wrong with your post, however maybe this will help you out a bit
Note : Make your code readable, trust me it does wonders
// List of threads
var threads = new List<Thread>();
// Lets stop indexing everything and make it easy for ourselves
var someList = myMT.Keys[key_indexer];
for (var i = 0; i < someList.Count; i++)
{
// we need to create a reference to the indexed value
// in the someList, otherwise there is no gaurentee
// the thread will have the right index when it needs it
// (thank me later)
var someSound = someList[i];
// create a thread and your callback
var thread = new Thread(() => someSound.PlayLooping());
// add thread to the list
threads.Add(thread);
}
// now lets start the treads in a nice orderly fashion
foreach (var thread in threads)
{
thread.Start();
}
Another way to do this with Tasks
var tasks = new List<Task>();
var someList = myMT.Keys[key_indexer];
for (var i = 0; i < someList.Count; i++)
{
var someSound = someList[1];
var task = new Task(() => someSound.PlayLooping());
tasks.Add(task);
task.Start();
}
Task.WaitAll(tasks.ToArray());
Disclaimer : i take no responsibility for your other logic problems, this was for pure morbid academic purposes

How to know that your application is not responding?

I have such particular code:
for (int i = 0; i < SingleR_mustBeWorkedUp._number_of_Requestes; i++)
{
Random myRnd = new Random(SingleR_mustBeWorkedUp._num_path);
while (true)
{
int k = myRnd.Next(start, end);
if (CanRequestBePutted(timeLineR, k, SingleR_mustBeWorkedUp._time_service, start + end) == true)
{
SingleR_mustBeWorkedUp.placement[i] = k;
break;
}
}
}
I use an infinite loop here which will end only if CanRequestBePutted returns true. So how to know that the app isn't responding?
There is a solution by controlling time of working each loop, but it doesn't seem to be really good. And I can't forecast that is going to happen in every cases.
Any solutions?
If you're concerned that this operation could potentially take long enough for the application's user to notice, you should be running it in a non-UI thread. Then you can be sure that it will not be making your application unrepsonsive. You should only be running it in the UI thread if you're sure it will always complete very quickly. When in doubt, go to a non-UI thread.
Don't try to figure out dynamically whether the operation will take a long time or not. If it taking a while is a possibility, do the work in another thread.
Why not use a task or threadpool so you're not blocking and put a timer on it?
The task could look something like this:
//put a class level variable
static object _padlock = new object();
var tasks = new List<Task>();
for (int i = 0; i < SingleR_mustBeWorkedUp._number_of_Requestes; i++)
{
var task = new Task(() =>
{
Random myRnd = new Random(SingleR_mustBeWorkedUp._num_path);
while (true)
{
int k = myRnd.Next(start, end);
if (CanRequestBePutted(timeLineR, k, SingleR_mustBeWorkedUp._time_service, start + end) == true)
{
lock(_padlock)
SingleR_mustBeWorkedUp.placement[i] = k;
break;
}
}
});
task.Start();
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
However I would also try to figure out a way to take out your while(true), which is a bit dangerous. Also Task requires .NET 4.0 or above and i'm not sure what framework your targeting.
If you need something older you can use ThreadPool.
Also you might want to put locks around shared resources like SingleR_mustBeWorkedUp.placement or anywhere else might be changing a variable. I put one around SingleR_mustBeWorkedUp.placement as an example.

C# Re-use or re-create tasks?

I have a while loop in which I create and start tasks, as follows:
while (!stopped)
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
tasks.add(Task.Factory.StartNew(() => DoSomething(i)));
Task.WaitAll(tasks.ToArray());
}
Would I get better performance if the tasks are created once before the while loop, and restarted everytime (because the data being passed to the function never changes)?
You can't restart task
http://msdn.microsoft.com/en-us/library/dd270682.aspx
By the way
Task.Factory.StartNew(() => {....})
is fast than
Task task = new Task(() => {...});
task.Start();
because no locking on Start method.
In your case use async io to get performance boost.
There is nothing fundamentally wrong with your code. This is a perfectly acceptable approach. You do not need to worry about the performance or expensive of creating tasks because the TPL was specifically designed to be used exactly like you have done.
However, there is one major problem with your code. You are closing over the loop variable. Remember, closures capture the variable and not the value. The way your code is written the DoSomething method will not be using the value of i that you think it should. Your code needs to be rewritten like this.
while (!stopped)
{
List tasks = new List();
for (int i = 0; i < 10; i++)
{
int capture = i;
tasks.add(Task.Factory.StartNew(() => DoSomething(capture)));
}
Task.WaitAll(tasks.ToArray());
}
As a side note you could use the Parallel.For method as an alternative. It is definitely a lot more compact of a solution if nothing else.
while (!stopped)
{
Parallel.For(0, 10, i => DoSomething(i));
}

Running threads in parallel, seems to be causing an infinite loop

It seems that if a given thread fails for any reason, this will cause an infinite loop.
This is code that isn't written by me so I can't even edit it, but I think the most obvious problem here is that the counter variable totalActions isn't marked as volatile, and as a result the threads are not seeing the most up-to-date value.
So it looks like if it never gets the real value of totalActions, it will keep waiting?
Will this cause the thread to run recursively then? While debugging, I notice that the executing thread fails (exception is thrown), and it just keeps getting called over and over and over....
public void PerformActions(List<Action> actions)
{
object actionLock = new object();
int totalActions = actionts.Count;
for(int x = 0; x < accounts.Count; x++)
{
int y = x;
new Thread(delegate()
{
actions[y].Invoke();
if(Interlocked.Decrement(ref totalActions) == 0)
{
lock(actionLock)
{
Monitor.Pulse(actionLock);
}
}
}).Start();
}
lock(actionLock)
{
if(totalActions > 0)
{
Monitor.Wait(actionLock);
}
}
}
Update
Usage is like this, where the myService is making httpRequest calls to grab json requests from an API service.
Execute.InParallel(
new Action[]
{
() => { abc = myService.DoSomething(); },
() => { def = myService.DoSomethingElse(); }
});
The lock will act as a memory barrier, ensuring that your test if(totalActions > 0) reads the current value. I'm not convinced that this code is race-free but the race would at least be very, very unlikely. You'd have a hard time reproducing it.
So the problem is something else not shown here. Can you use the debugger to find out what exactly the threads involved are doing?
You say some threads die due to an unhandled exception. Maybe the threads exiting early causes the count not to decrement.
Also, if you can't change the code, what is the point of the question? I'm not sure what to suggest to you.
The loop is incorrect - in that variable x is captured incorrectly. it will always have the last value of x when actions[x].Invoke(); is executed in each thread. So, the last delegate passed to array will be called multiple times.
Correct way to do it is like this
for(int x = 0; x < accounts.Count; x++)
{
int y = x; // here correct value of y will be captured in delegate
new Thread(delegate()
{
actions[y].Invoke();
...

C# Anonymous Thread with Lambda Syntax

In general I get C#'s lambda syntax. However the anonymous thread syntax isn't completely clear to me. Can someone explain what a thread creation like this is actually doing? Please be as detailed as possible, I'd love to have a sort of step-by-step on the magic that makes this work.
(new Thread(() => {
DoLongRunningWork();
MessageBox.Show("Long Running Work Finished!");
})).Start();
The part that I really don't understand is the Thread(() => ...
When I use this syntax it seems like I remove a lot of the limits of a traditional ThreadStart such as having to invoke on a method that has no parameters.
Thanks for your help!
() => ... just means that the lambda expression takes no parameters. Your example is equivalent to the following:
void worker()
{
DoLongRunningWork();
MessageBox.Show("Long Running Work Finished!");
}
// ...
new Thread(worker).Start();
The { ... } in the lambda let you use multiple statements in the lambda body, where ordinarily you'd only be allowed an expression.
This:
() => 1 + 2
Is equivalent to:
() => { return (1 + 2); }
This is anonymous way to create a thread in C# which just start the thread (because you are using Start();)
Following 2 ways are equivalent. If you need Thread variable to do something (for example block the calling thread by calling thread0.join()), then you use the 2nd one.
new Thread(() =>
{
Console.WriteLine("Anonymous Thread job goes here...");
}).Start();
var thread0= new Thread(() =>
{
Console.WriteLine("Named Thread job goes here...");
});
thread0.Start();
Now the Thread method part. If you see the Thread declaration we have the following (I omitted 3 others).
public Thread(ThreadStart start);
Thread takes a delegate as a parameter. Delegate is reference to a method. So Thread takes a parameter which is a delegate. ThreadStart is declared like this.
public delegate void ThreadStart();
It means you can pass any method to Thread which return void and doesn't take any parameters. So following examples are equivalent.
ThreadStart del = new ThreadStart(ThreadMethod);
var thread3 = new Thread(del);
thread3.Start();
ThreadStart del2 = ThreadMethod;
var thread4 = new Thread(del2);
thread4.Start();
var thread5 = new Thread(ThreadMethod);
thread5.Start();
//This must be separate method
public static void ThreadMethod()
{
Console.WriteLine("ThreadMethod doing important job...");
}
Now we think that ThreadMethod method is doing little work we can make it to local and anonymous. So we don't need the ThreadMethod method at all.
new Thread( delegate ()
{
Console.WriteLine("Anonymous method Thread job goes here...");
}).Start();
You see after delegate to last curly braces is equivalent to our ThreadMethod(). You can further shorten the previous code by introducing Lambda statement (See MSDN). This is just you are using and see how it has been ended up like the following.
new Thread( () =>
{
Console.WriteLine("Lambda statements for thread goes here...");
}).Start();
As there was some answers before I started, I will just write about how additional parameters make their way into lambda.
In short this thing called closure. Lets dissect your example with new Thread(() => _Transaction_Finalize_Worker(transId, machine, info, newConfigPath)).Start(); into pieces.
For closure there's a difference between class' fields and local variables. Thus let's assume that transId is class field (thus accessible through this.transId) and others are just local variables.
Behind the scenes if lambda used in a class compiler creates nested class with unspeakable name, lets name it X for simplicity, and puts all local variables there. Also it writes lambda there, so it becomes normal method. Then compiler rewrites your method so that it creates X at some point and replaces access to machine, info and newConfigPath with x.machine, x.info and x.newConfigPath respectively. Also X receives reference to this, so lambda-method could access transId via parentRef.transId.
Well, it is extremely simplified but near to reality.
UPD:
class A
{
private int b;
private int Call(int m, int n)
{
return m + n;
}
private void Method()
{
int a = 5;
a += 5;
Func<int> lambda = () => Call(a, b);
Console.WriteLine(lambda());
}
#region compiler rewrites Method to RewrittenMethod and adds nested class X
private class X
{
private readonly A _parentRef;
public int a;
public X(A parentRef)
{
_parentRef = parentRef;
}
public int Lambda()
{
return _parentRef.Call(a, _parentRef.b);
}
}
private void RewrittenMethod()
{
X x = new X(this);
x.a += 5;
Console.WriteLine(x.Lambda());
}
#endregion
}

Categories