I am trying to splice the work on multiple threads using ThreadPooling. I wanna use every available thread to assign (and calculate in a different part of the program down the line) the output of an array member to another array members.
It does work, but it is much slower than just adding them on a single thread. Is my usage wrong or is this operation too simple for multithreading?
arrayI and arrayX variables are in classScope, i couldnt pass them as QueueUserWorkItem argument without converting them in setNeuronInput.
if (layerType != 0)
{
for (arrayI = 0; arrayI < layerSize -1 ; arrayI++)
{
for (arrayX = 0; arrayX < network.Layers[layerIndex - 1].layerSize - 1; arrayX++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(setNeuronInput), null);
//Neurons[i].input[x] = _network.Layers[layerIndex - 1].Neurons[x].output;
}
}
}
//ThreadPool.GetAvailableThreads(out availableThreads, out placeHolder);
//while (availableThreads != maxThreads)
//{
// ThreadPool.GetAvailableThreads(out availableThreads, out placeHolder);
//}
//return;
}
public void setNeuronInput(object o)
{
try
{
//Console.WriteLine("Thread is working");
Neurons[arrayI].input[arrayX] = network.Layers[layerIndex - 1].Neurons[arrayX].output;
}
catch(Exception e)
{
Console.WriteLine(e);
Console.WriteLine("ArrayI is : " + arrayI);
Console.WriteLine("ArrayX is : " + arrayX);
Console.ReadLine();
}
}
Related
I am trying to use lock for read and write to list at the same time. I adding bytes from serial port to a list while processing these bytes by reading from same list with the help of lock. My problem is that while running it in debug mode it is working fine but while running normally it showing exception. Following is my code.
private void receiveData(object sender, SerialDataReceivedEventArgs e)
{
while (connectComPort.BytesToRead > 0)
receivedBytes1.Add((byte)connectComPort.ReadByte());
}
int tint = 0;
private static readonly object _object = new object();
private void modprocessReceivedBuffer()
{
while (1 == 1)
{
try
{
if (receivedBytes1.Count() > tint)
{
List<byte> receivedBytes12 = null;
lock (_object)
{
receivedBytes12 = receivedBytes1.GetRange(tint, 2).ToList<byte>(); //LINE 1
}
if (receivedBytes12[0] == 0x0D)
{
if (receivedBytes12[1] == 0xAF)
{
try
{
var tiff = receivedBytes1.GetRange(tint, ((int)receivedBytes1[tint + 4])).ToList<byte>();
tint += (int)receivedBytes1[tint + 4];
modifiedProcess(tiff);
if (receivedBytes1.Count() == tint)
{
receivedBytes1.Clear();
tint = 0;
Thread.Sleep(20);
}
}
catch
{
}
}
}
else
{
tint += 1;
}
}
}
catch (Exception ex)
{
Log.Error("bug : " + ex.ToString());
}
}
}
Line 1 shows "System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection" while running the code normally. I am not able to catch this error while running in debug mode. My second question is that if their is any thread safe list like structure in c#?
I would also like to add that I am receiving data from port at a very fast rate 16000 bytes/sec average.
Below is a function I have running in a while(true) loop in a thread running a Winforms GUI.
I have a button set to put text data into the inBuffer object. this always works, however when I place into the buffer object from a different thread, the data is detected, pulled, and printed out in the Console.out.WriteLine statement, however it never shows up in the Display (textBox) object
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != "")
{
Console.Out.WriteLine("FOUND SOMETHING IN BUFFER: " + strDisplayMe);
char[] DisplayMeArr = strDisplayMe.ToCharArray ();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
this.display.Text += DisplayMeArr [i];
Thread.Sleep (100);
}
this.display.Text += '\n';
}
}
EDIT: this is a separate class from what is feeding it data through the static buffer objects
Only the main window thread can access/change controls... if you want update the UI from the thread that runs the loop, you need to sync the call with the main thread using the Control.Invoke method.
For instance...
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != string.Empty)
{
char[] DisplayMeArr = strDisplayMe.ToCharArray();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
this.UpdateUI(() => { this.display.Text += DisplayMeArr[i]; });
Thread.Sleep(100);
}
this.UpdateUI(() => { this.display.Text += '\n'; });
}
}
private void UpdateUI(Action handler)
{
this.Invoke(handler);
}
You can use MethodInvoker to access TextBox from other thread then GUI thread. Make a method to access the TextBox using MethodInvoker. you are assigning text multiple times consider assigning it once for performance, and use StringBuilder for string concatenation.
public void put()
{
string strDisplayMe = ModemKind.MainClass.inBuffer.MkRequest();
if (strDisplayMe != "")
{
Console.Out.WriteLine("FOUND SOMETHING IN BUFFER: " + strDisplayMe);
char[] DisplayMeArr = strDisplayMe.ToCharArray ();
for (int i = 0; i <= DisplayMeArr.Length -1; ++i)
{
AssignToTextBox(this.display, this.display.Text + DisplayMeArr [i]);
Thread.Sleep (100);
}
AssignToTextBox(this.display, this.display.Text + '\n');
}
}
void AssignToTextBox(TextBox txtBox, string value)
{
if(txtBox.InvokeRequired)
{
txtBox.Invoke(new MethodInvoker(delegate { txtBox.text = value; }));
}
}
Edit You can use BeginInvoke instead of Invoke to call it asynchronously. Read more about the Invoke and BeginInvoke in this question.
void AssignToTextBox(TextBox txtBox, string value)
{
txtBox.BeginInvoke(new Action(()=>txtBox.Text = value ));
}
I have one problem. In my project i need for more then 100 threads, that's why i prefer to use ThreadPool. here is a part of code, but in this case i have got a lot of memory usage and my form is very laggy, cuz of A lot of BeginInvoke calls(i suppose).
Is there any solutions for this problem?
public void launch()
{
while (data.Count > 0)
{
string[] part;
if (data.Count> 1000)
{
part = data.Take(1000).ToArray();
data = data.Skip(1000).ToList();
}
else
{
part = data.Take(data.Count).ToArray(); data = data.Skip(1000).ToList();
}
foreach (var input in part)
{
try
{
char splitter = ':';
if (input.Contains(';')) splitter = ';';
string login = input.Split(splitter)[0];
string pass = input.Split(splitter)[1];
EncryptCore ec = new EncryptCore(new byte[15]);
PacketSend ps = new PacketSend(ec, "");
ps._login = login;
ps._password = pass;
ps.Brutted+=ps_Parsed;
ps.Failed+=ps_Failed;
ThreadPool.QueueUserWorkItem(ps.Parse);
}
catch { Interlocked.Increment(ref curr); }
}
Thread.Sleep(1000);
}
data.Clear();
}
private void ps_Brutted(User Account)
{
toGet.Add(Account);
Interlocked.Increment(ref good);
goodLabl.BeginInvoke(new Action(delegate()
{
goodLabl.Text = "Good: " + good;
}));
Update();
}
private void Update()
{
try
{
Interlocked.Increment(ref curr);
progLabel.BeginInvoke(new Action(delegate()
{
progLabel.Text = (double.Parse(curr.ToString()) / double.Parse(max.ToString())).ToString("#%");
}));
progressBar.BeginInvoke(new Action(delegate()
{
progressBar.Text = (double.Parse(curr.ToString()) / double.Parse(max.ToString()) * 100).ToString("#");
}));
checkedLabl.BeginInvoke(new Action(delegate()
{
checkedLabl.Text = "Checked: " + curr + " / " + max;
}));
}
catch { }
}
So you have thousands of tasks, and each time one of them completes you update the UI by scheduling 4 updates on the UI thread. What you might consider doing is having the UI update on a timer-based schedule (try 100ms or 200ms) based on the integers that are updating.
Aside from that, you've got some strange numeric operations going on. You can just cast an int to a double, you don't have to round-trip through a String.
I've made this producer-consumer sample, but I don't know why it freezes at the end.
Where is the problem? If I put a breakpoint at line setNum(-99); and then after break continue it finishes OK.
Please also tell me if this code is ok and threadsafe. It must work like that, so meanwhile consumer is processing its given value, all other values from producer must be ignored.
I am very new to multithreading.
class Program
{
delegate void SetNumberDelegate(int number);
static void Main(string[] args)
{
Random rnd = new Random();
ConsumerClass consumerClass = new ConsumerClass();
SetNumberDelegate setNum = new SetNumberDelegate(consumerClass.setNumber);
Thread.Sleep(20);
int num;
int count = 0;
Console.WriteLine("Start");
while (count++ < 100)
{
num = rnd.Next(0, 100);
Console.WriteLine("Generated number {0}", num);
if (num > 30)
{
setNum(num);
}
}
setNum(-99);
Console.WriteLine("End");
Console.ReadKey();
}
}
class ConsumerClass : IDisposable
{
private int number;
private object locker = new object();
private EventWaitHandle _wh = new AutoResetEvent(false);
private Thread _consumerThread;
public ConsumerClass()
{
number = -1;
_consumerThread = new Thread(consumeNumbers);
_consumerThread.Start();
}
public void Dispose()
{
setNumber(-99);
_consumerThread.Join();
_wh.Close();
}
public void setNumber(int num)
{
if (Monitor.TryEnter(locker))
{
try
{
number = num;
Console.WriteLine("Setting number {0}", number);
}
finally
{
// Ensure that the lock is released.
Monitor.Exit(locker);
}
_wh.Set();
}
}
public void consumeNumbers()
{
while (true)
{
Monitor.Enter(locker);
if (number > -1)
{
try
{
Console.WriteLine("Processing number:{0}", number);
// simulate some work with number e.g. computing and storing to db
Thread.Sleep(20);
Console.WriteLine("Done");
number = -1;
}
finally
{
Monitor.Exit(locker);
}
}
else
{
if (number == -99)
{
Console.WriteLine("Consumer thread exit");
return;
}
Monitor.Exit(locker);
_wh.WaitOne(); // No more tasks - wait for a signal
}
}
}
}
Rewrite setNumber like this to see your problem:
public void setNumber(int num) {
if (Monitor.TryEnter(locker)) {
// etc..
}
else Console.WriteLine("Number {0} will never make it to the consumer", num);
}
You'll have to block, waiting for the consumer to be ready to consume or use a queue.
Monitor.TryEnter(locker); will usually fail (including for -99) so you aren't going to set a fair number of the values, which is why the output is lacking in setting statements. This is because it will not wait to acquire the lock it will just return false.
The problem appears to be in the last part of the code. You're holding the lock when you execute this:
else
{
if (number == -99)
{
Console.WriteLine("Consumer thread exit");
return;
}
Monitor.Exit(locker);
_wh.WaitOne(); // No more tasks - wait for a signal
}
So if number == 99, the method returns without releasing the lock.
Your ConsumeNumbers method is overly complex. You can simplify it:
while (true)
{
_wh.WaitOne();
lock (locker)
{
if (number == -99)
break;
if (number > -1)
{
// process the number.
number = -1;
}
}
}
That will do the same thing, and is much simpler code.
By the way, the construct:
lock (locker)
{
// do stuff here
}
is the same as:
Monitor.Enter(locker);
try
{
// do stuff here
}
finally
{
Monitor.Exit(locker);
}
I'm attempting to write a function which starts a thread for each "contact" and then queries (over the network) for results from that contact. I want my waiting function to wait at most 1.5 second for responses, and after that, simply terminate any remaining threads.
The issue I'm having is that the function is returning before all the threads are done, even though according to the logic, this should not be possible. The while loop in the main function should be waiting until all threads have fully completed, yet I get the following output:
FAIL: Storage test 1 exists 0 times in the DHT.
: Storage test 2 exists 0 times in the DHT.
Added storage test 1 to the entries.
Added storage test 2 to the entries.
(The FAIL lines comes from the main testing program seeing how many results were returned by Get().)
According to what I can see, this shouldn't be possible. Does anyone know where the race condition might be occurring (or any other assumptions I've made that are not correct)?
The function definition is as such:
public IList<Entry> Get(ID key)
{
ConcurrentBag<Entry> entries = new ConcurrentBag<Entry>();
List<Thread> threads = new List<Thread>();
foreach (Contact c in this.p_Contacts)
{
Thread t = new Thread(delegate()
{
try
{
FetchMessage fm = new FetchMessage(this, c, key);
fm.Send();
int ticks = 0;
// Wait until we receive data, or timeout.
while (!fm.Received && ticks < 1500)
{
Thread.Sleep(100);
ticks += 100;
}
if (fm.Received)
{
foreach (Entry e in fm.Values)
{
Console.WriteLine("Added " + e.Value + " to the entries.");
entries.Add(e);
}
if (entries.Count == 0)
Console.WriteLine("There were no entries to add.");
}
else
Console.WriteLine("The node did not return in time.");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
);
t.IsBackground = false;
t.Start();
}
while (true)
{
bool stopped = true;
foreach (Thread t in threads)
{
if (t.ThreadState != ThreadState.Stopped)
stopped = false;
}
if (stopped)
break;
Thread.Sleep(100);
}
return new List<Entry>(entries.ToArray());
}
Looks like you're never putting the Thread (t) in the List<Thread> (threads). Your foreach loop never executes.
The main thread just waits 100ms and continues.
#Toby has the correct answer, but if I may introduce some other things to improve the code. Essentially, you are manually managing your own ThreadPool and timeouts--and this is something that .Net provides for you out of the box. See: http://msdn.microsoft.com/en-us/library/system.threading.threadpool(v=VS.100).aspx
If you combine your ThreadPool with a .Net 4 Barrier, you can simplify the code a lot. Essentially, a Barrier will block all threads until they sync up. When you pass in the same barrier to your threads and sync up at the end, you can pause your main thread until all the worker threads are done. The refactored code would look like this:
// For the number of threads + 1 for the main thread
Barrier barrier = new Barrier(this.p_Contacts.count + 1);
ConcurrentBag<Entry> entries = new ConcurrentBag<Entry>();
foreach (Contact c in this.p_Contacts)
{
ThreadPool.RegisterWaitForSingleObject(
new EventWaitHandle(false, EventResetMode.AutoReset),
(stateInfo,timedOut) => {
try
{
FetchMessage fm = new FetchMessage(this, c, key);
fm.Send();
while(!fm.Received || !timedOut)
{
Thread.Sleep(100);
}
if(fm.Received)
{
foreach (Entry e in fm.Values)
{
entries.Add(e);
Console.WriteLine("Added " + e.Value + " to the entries.");
}
// avoid counting other thread's work
if (fm.Values.count == 0)
{
Console.WriteLine("There were no entries to add.");
}
}
else
{
Console.WriteLine("The node did not return in time.");
}
barrier.SignalAndWait();
}
catch(Exception e)
{
Console.WriteLine(e);
}
}, null, TimeSpan.FromSeconds(1.5), true);
);
}
// This limits total time waited to only 1.5 seconds
barrier.SignalAndWait(TimeSpan.FromSeconds(1.5));
return new List<Entry>(entries.ToArray());
Instead of manually managing the spin locks like you were doing, let .Net do it for you.
The Threads don't get added to your list so the while loop will break right away?
The solution to this problem was to use a ConcurrentDictionary to keep track of the contacts that had their threads finished:
public IList<Entry> Get(ID key)
{
ConcurrentBag<Entry> entries = new ConcurrentBag<Entry>();
ConcurrentDictionary<Contact, bool> done = new ConcurrentDictionary<Contact, bool>();
List<Thread> threads = new List<Thread>();
foreach (Contact c in this.p_Contacts)
{
Thread t;
ThreadStart ts = delegate()
{
try
{
FetchMessage fm = new FetchMessage(this, c, key);
fm.Send();
int ticks = 0;
// Wait until we receive data, or timeout.
while (!fm.Received && ticks < 1500)
{
Thread.Sleep(100);
ticks += 100;
}
if (fm.Received)
{
foreach (Entry e in fm.Values)
{
Console.WriteLine("Added " + e.Value + " to the entries.");
entries.Add(e);
}
if (entries.Count == 0)
Console.WriteLine("There were no entries to add.");
}
else
Console.WriteLine("The node did not return in time.");
Thread.MemoryBarrier();
done[c] = true;
}
catch (Exception e)
{
Console.WriteLine(e);
}
};
t = new Thread(ts);
done[c] = false;
t.IsBackground = true;
t.Start();
}
while (true)
{
bool stopped = true;
foreach (Contact c in this.p_Contacts)
{
if (!done[c])
stopped = false;
}
if (stopped)
break;
Thread.Sleep(100);
}
return new List<Entry>(entries.ToArray());
}