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

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();
...

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

Call a method and cancel it and return to the calling method if it takes too long

Is there a way in c# to call a method so that if the method takes to long to complete, the method will be canceled and it will return to the calling method? I think I can do this with threading but what if threading is not needed?
For reference, the method I may need to kill/stop/abort is calling the CorelDraw 15 API. This opens an instance of CorelDraw and I have received non-repeatable errors in this method. Meaning, I can process the same image twice and one time it will freeze or error and the other it will not.
The current solution to the issue I am using is to have a second application that does Process.Start(firstAppExecutablePath) and then checks a variable in a text file and if the variable doesn't change after 10 minutes, .Kill(); is called on the instance of the process. I would prefer to avoid this solution if possible as it seems clunky and prone to issues. Since it runs .Kill(); it is being very messy in how things close but generally does not cause an issue.
Not built-in, no, since interrupting arbitrary code cannot be done safely (what if it's in the middle of calling a C library function (that doesn't support exceptions) which has just taken a global lock and needs to release it?).
But you can write such support yourself. I wouldn't add threads to the mix unless absolutely necessary, since they come with an entire new dimension of potential problems.
Example:
void Caller()
{
int result;
if (TryDoSomething(out result, 100)) {
System.Console.WriteLine("Result: {0}", result);
}
}
bool TryDoSomething(out int result, int timeoutMillis)
{
var sw = Stopwatch.StartNew();
result = 0x12345678;
for (int i = 0; i != 100000000; ++i) {
if (sw.ElapsedMilliseconds > timeoutMillis)
return false;
result += i / (result % 43) + (i % 19);
}
return true;
}
Threading is absolutely needed unless you are ok with checking the timeout from within the function - which probably you arn't. So here is a minimalistic approach with threads:
private static bool ExecuteWithTimeout(TimeSpan timeout, Action action)
{
Thread x = new Thread(() => { action(); });
x.Start();
if (!x.Join(timeout))
{
x.Abort(); //Or Interrupt instead, if you use e.g. Thread.Sleep in your method
return false;
}
return true;
}

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.

For loop cause IndexOutOfBoundException

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();
}

Csharp threading starting new threads when one finished without waiting on join

I've searched all morning and I can't seem to find the answer to this question.
I have an array of Threads each doing work and then I'll loop through the ids joining each one then starting new threads. What's the best way to detect when a thread has finish so I can fire off a new thread without waiting for each thread to finish?
EDIT added code snippet maybe this will help
if (threadCount > maxItems)
{
threadCount = maxItems;
}
threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(delegate() { this.StartThread(); });
threads[i].Start();
}
while (loopCounter < threadCount)
{
if (loopCounter == (threadCount - 1))
{
loopCounter = 0;
}
if (threads[loopCounter].ThreadState == ThreadState.Stopped)
{
threads[loopCounter] = new Thread(delegate() { this.StartThread(); });
threads[loopCounter].Start();
}
}
Rather than creating new thread each time, why not just have each thread call a function that returns the next ID (or null if there's no more data to process) when it's finished with the current one? That function will obviously have to be threadsafe, but should reduce your overhead versus watching for finished threads and starting new ones.
so,
void RunWorkerThreads(int threadCount) {
for (int i = 0; i < threadCount; ++i) {
new Thread(() => {
while(true) {
var nextItem = GetNextItem();
if (nextItem == null) break;
/*do work*/
}
}).Start();
}
}
T GetNextItem() {
lock(_lockObject) {
//return the next item
}
}
I'd probably pull GetNextItem and "do work" out and pass them as a parameters to RunWorkerThreads to make that more generic -- so it would be RunWorkerThreads<T>(int count, Func<T> getNextItem, Action<T> workDoer), but that's up to you.
Note that Parallel.ForEach() does essentially this though plus give ways of monitoring and aborting and such, so there's probably no need to reinvent the wheel here.
You can check the thread's ThreadState property and when it's Stopped you can kick off a new thread.
http://msdn.microsoft.com/en-us/library/system.threading.thread.threadstate.aspx
http://msdn.microsoft.com/en-us/library/system.threading.threadstate.aspx
Get each thread, as the last thing it does, to signal that it is done. That way there needs to be no waiting at all.
Even better move to a higher level of abstraction, e.g. threadpool and let someone else worry about such details.

Categories