I have a try/catch block and within catch am trying to apply a pause but no matter what method I try (pause, threadsleep) it simply continues. and ignores all pauses in the mainblock. Is this a .NET bug?
catch (Exception ex)
{
if (maxDelay < 1)
maxDelay = 1;
newpause(maxDelay);
// Pause(maxDelay * 60);
Current = "Error:" + txt;
LogUpdater.UpdateLog(f, "Error sending : " + txt + ".");
System.Threading.Thread.Sleep(10);
bw.ReportProgress(1);
}
public void newpause(int maxDelay)
{
for (int i = 0; i < 60; i++)
{
System.Threading.Thread.Sleep(maxDelay*1000);
Application.DoEvents();
}
}
Please try running following code. It works on my side.
class PauseExample
{
static void Main(string[] args)
{
int a = 90;
int b = 0;
try
{
int c = a / b;
}
catch
{
Console.WriteLine("In catch");
System.Threading.Thread.Sleep(5000); //waits for 5 seconds
Console.WriteLine("Out of catch");
}
}
}
Let me know if this helps!
Your passing one/tenth of a second.
Your only passing 10 milliseconds, 1000 would be 1 second.
System.Threading.Thread.Sleep(1000); // One Second.
Related
I have some code below that goes through all the directories of a given area sDir it also runs on it's own thread. This builds a liststring that then gets converted to an array to build a treeview.
However I would also like to count the number of directories and files that the search is up to and display it on my UI. If i add the this.Invoke((MethodInvoker)(() => DirCL.Text = "Dir: " + dirC.ToString()));
and the this.Invoke((MethodInvoker)(() => FileCL.Text = "Files: " + FileC.ToString()));
liststring.Add(Files);
This makes the function go from 10 seconds to do an area with 65,000 files to 100ish seconds.
I assume this Increase is because the MethodInvoker is pausing the function to go write to the UI.
Is there a better way for me to be writing code to the UI that is in a different thread?
int dirC = 0;
int FileC = 0;
private void DirSearch(string sDir)
{
try
{
string[] array1 = Directory.GetDirectories(sDir);
for (int i1 = 0; i1 < array1.Length; i1++)
{
string Dir = array1[i1];
dirC++;
//this.Invoke((MethodInvoker)(() => DirCL.Text = "Dir: " + dirC.ToString()));
try
{
String[] array = Directory.GetFiles(Dir, txtFile.Text);
for (int i = 0; i < array.Length; i++)
{
string Files = array[i];
FileC++;
//this.Invoke((MethodInvoker)(() => FileCL.Text = "Files: " + FileC.ToString()));
liststring.Add(Files);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
DirSearch(Dir);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
ErrC++;
}
}
I am probably just doing it very wrong. I am currently working with MSMQ and Webservices. I wanted to learn how MSMQ worked so I found a school example of a Loan Broker.
To make a long story short, I need to be able to stress test my system, so I want to be able to make, say, 100 messages and send them through my messaging system. I want to do that from a Windows Form application, but here lies the problem. I have a form that looks like this:
On the left you see a custom control and on the right, my "console" window that tells me what's going on. When I press the Send button, it should use the data given in the fields above it, to send messages. But when I press the Send Button, the program freezes for a while and then hits the OutOfMemoryException. This is the Send method:
private void Send(List<SimpleRequest.LoanRequest> list)
{
int quantity = int.Parse(numericQuantity.Value.ToString());
int delay = int.Parse(numericDelay.Value.ToString());
if (list.Count == 1)
{
for (int threadnumber = 0; threadnumber < quantity; threadnumber++)
{
Task.Factory.StartNew(() => RequestLoanQuote(threadnumber, list[0]));
if (delay > 0)
{
Thread.Sleep(delay);
}
}
}
else
{
for (int threadnumber = 0; threadnumber < quantity; threadnumber++)
{
Task.Factory.StartNew(() => RequestLoanQuote(threadnumber, list[threadnumber]));
if (delay > 0)
{
Thread.Sleep(delay);
}
}
}
}
Here is the RequestLoanQuote method that the Send method is calling:
private void RequestLoanQuote(object state, SimpleRequest.LoanRequest loanRequest)
{
try
{
if (console.InvokeRequired)
{
SetText("Sending: " + loanRequest.SSN + "\n");
}
StringBuilder sb = new StringBuilder();
var threadnumber = (int)state;
using (var client = new LoanBrokerWS.LoanBrokerWSClient())
{
Utility_Tool.LoanBrokerWS.LoanQuote response = client.GetLoanQuote(loanRequest.SSN, loanRequest.LoanAmount, loanRequest.LoanDuration);
sb.Append(response.SSNk__BackingField + " returned: ");
sb.Append(response.interestRatek__BackingField + " | ");
sb.Append(response.BankNamek__BackingField + "\n");
SetText(sb.ToString());
}
}
catch (Exception e)
{
SetText(e.Message + "\n");
}
}
And finally, the SetText method:
private void SetText(String msg)
{
if (this.console.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { msg });
}
else
{
this.console.Text += msg;
}
}
So the Send method calls the RequestLoanQuote method which calls the SetText method. I cannot figure out where I went wrong but it's probably a deadlock.
Try using BeginInvoke and AppendText, like so:
public static void SetText(this RichTextBox textBox, string msg)
{
Action append = () => textBox.AppendText(msg);
if (textBox.InvokeRequired)
textBox.BeginInvoke(append);
else
append();
}
Here's a simple program:
class Program
{
static Calc calc = new Calc();
static void Main(string[] args)
{
try
{
var t1 = new Thread(calc.Divide);
t1.Start();
}
catch (DivideByZeroException e)
{
//Console.WriteLine("Error thread: " + e.Message);
}
try
{
calc.Divide();
}
catch (Exception e)
{
//Console.WriteLine("Error calc: " + e.Message);
}
}
class Calc
{
public int Num1;
public int Num2;
Random random = new Random();
public void Divide()
{
for (int i = 0; i < 100000; i++)
{
Num1 = random.Next(1, 10);
Num2 = random.Next(1, 10);
try
{
int result = Num1 / Num2;
}
catch (Exception ex)
{
throw ex;
}
Num1 = 0;
Num2 = 0;
}
}
}
}
Two threads are executing same method at the same time. One of them sets Num1 to 0 while the other one is trying to divide by Num1 (0) at the same time. The question is why is exception thrown, why it's not caught by try catch block inside the Main method?
Main thread is one thread and your new thread is another thread. Those two threads does not talk to each other meaning that they are totally independent. If you want to catch the exception on your main thread there are two ways of doing it
Use a backgroundworker class, the RunWorkerCompleted event will be fired on main thread, e.exception will tell you if an exception caused the thread to be aborted.
Use a global catcher
add this line before your codes
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
and
void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
//handle the exception
}
Following is the code that I use. The main thread waits for Threadpool threads to execute. I use AutoResetEvent (WaitHandle), but I am really surprised that I am way off the mark, as the code doesn't behave as expected.
I have two concentric for loops, where Threadpool is in the inner loop and it is expected that for each iteration of the outer loop, all the inner loop values should be processed. Main thread is made to wait using AutoResetEvent WaitOne call just outside inner loop, a static variable which is reset on every iteration of the outerloop to the max value of the inner loop, and is decremented using Interlock in the method call on Threadpool thread is used to call the Set for the AutoResetEvent. However, even when I expect the static variable to show the value 0 after every inner loop, it doesn't. What is the issue in my code and what are better options for me to accomplish the task? In fact, due to the mix up of the values, the main thread doesn't really seem to be waiting for the Threadpool threads.
using System;
using System.Threading;
namespace TestThreads
{
class Program
{
private static int threadingCounter = 0;
private static readonly object lockThreads = new Object();
private AutoResetEvent areSync = new AutoResetEvent(true);
// <param name="args"></param>
static void Main(string[] args)
{
Program myProgram = new Program();
try
{
try
{
for (int outer = 0; outer < 1000; outer++)
{
threadingCounter = 500;
try
{
for (int inner = 0; inner < 500; inner++)
{
ThreadPool.QueueUserWorkItem(new
WaitCallback(myProgram.ThreadCall), inner);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
myProgram.areSync.WaitOne();
}
if(threadingCounter != 0)
Console.WriteLine("In Loop1, Thread Counter :: " +
threadingCounter);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
}
catch(Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
threadingCounter = 0;
if (myProgram.areSync != null)
{
myProgram.areSync.Dispose();
myProgram.areSync = null;
}
}
}
public void ThreadCall(object state)
{
try
{
int inner = (int)state;
Thread.Sleep(1);
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
Interlocked.Decrement(ref threadingCounter);
if (threadingCounter <= 0)
areSync.Set();
}
}
}
}
You have initialized AutoResetEvent with initial state as signaled(true) which will allow first call to
myProgram.areSync.WaitOne();
to continue without blocking, so it continues to outer loop and Queues execution to Threadpool again, hence the results are messed up. it is very clear.
update your code to
private AutoResetEvent areSync = new AutoResetEvent(false);
for expected results. hope this helps
I would refactor this using something like this. This assumes you want to do something in background threads in your inner loop, finish each of those before proceeding with your next outer loop, avoid messy exception handling while still capturing the exceptions that occurred during processing so that you can deal with those exceptions after processing is complete for both inner and outer loop.
// track exceptions that occurred in loops
class ErrorInfo
{
public Exception Error { get; set; }
public int Outer { get; set; }
public int Inner { get; set; }
}
class Program
{
static void Main(string[] args)
{
// something to store execeptions from inner thread loop
var errors = new ConcurrentBag<ErrorInfo>();
// no need to wrap a try around this simple loop
// unless you want an exception to stop the loop
for (int outer = 0; outer < 10; outer++)
{
var tasks = new Task[50];
for (int inner = 0; inner < 50; inner++)
{
var outerLocal = outer;
var innerLocal = inner;
tasks[inner] = Task.Factory.StartNew(() =>
{
try
{
Thread.Sleep(innerLocal);
if (innerLocal % 5 == 0)
{
throw new Exception("Test of " + innerLocal);
}
}
catch (Exception e)
{
errors.Add(new ErrorInfo
{
Error = e,
Inner = innerLocal,
Outer = outerLocal
});
}
});
}
Task.WaitAll(tasks);
}
Console.WriteLine("Error bag contains {0} errors.", errors.Count);
Console.ReadLine();
}
}
I have a programming that is looping x times (10), and using a specified number of threads (2). I'm using a thread array:
Thread[] myThreadArray = new Thread[2];
My loop counter, I believe, starts the first 2 threads just fine, but when it gets to loop 3, which goes back to thread 0 (zero-based), it hangs. The weird thing is, if I throw a MessageBox.Show() in their to check the ThreadState (which shows thread 0 is still running), it will continue on through 9 of the 10 loops. But if no MessageBox.Show() is there, it hangs when starting the 3rd loop.
I'm using .NET 3.5 Framework (I noticed that .NET 4.0 utilizes something called continuations...)
Here's some code examples:
Thread[] threads = new Thread[2];
int threadCounter = 0;
for (int counter = 0; counter < 10; counter++)
{
if (chkUseThreading.Checked)
{
TestRunResult runResult = new TestRunResult(counter + 1);
TestInfo tInfo = new TestInfo(conn, comm, runResult);
if (threads[threadCounter] != null)
{
// If this is here, then it will continue looping....otherwise, it hangs on the 3rd loop
MessageBox.Show(threads[threadCounter].ThreadState.ToString());
while (threads[threadCounter].IsAlive || threads[threadCounter].ThreadState == ThreadState.Running)
Thread.Sleep(1);
threads[threadCounter] = null;
}
// ExecuteTest is a non-static method
threads[threadCounter] = new Thread(new ThreadStart(delegate { ExecuteTest(tInfo); }));
threads[threadCounter].Name = "PerformanceTest" + (counter + 1);
try
{
threads[threadCounter].Start();
if ((threadCounter + 1) == threadCount)
threadCounter = 0;
else
threadCounter++;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Application.DoEvents();
}
}
while (true)
{
int threadsFinished = 0;
for (int counter = 0; counter < threadCount; counter++)
{
if (!threads[counter].IsAlive || threads[counter].ThreadState == ThreadState.Stopped)
threadsFinished++;
}
if (threadsFinished == threadCount)
break;
else
Thread.Sleep(1);
}
Obviously the problem is something about how I'm checking to see if thread #1 or #2 is done. The IsAlive always says true, and the ThreadState always has "running" for threads loops 1 and 10.
Where am I going wrong with this?
Update, here's the ExecuteTask() method:
private void ExecuteTest(object tInfo)
{
TestInfo testInfo = tInfo as TestInfo;
Exception error = null;
DateTime endTime;
TimeSpan duration;
DateTime startTime = DateTime.Now;
try
{
if (testInfo.Connection.State != ConnectionState.Open)
{
testInfo.Connection.ConnectionString = connString;
testInfo.Connection.Open();
}
testInfo.Command.ExecuteScalar();
}
catch (Exception ex)
{
error = ex;
failedCounter++;
//if (chkCancelOnError.Checked)
// break;
}
finally
{
endTime = DateTime.Now;
duration = endTime - startTime;
RunTimes.Add(duration);
testInfo.Result.StartTime = startTime;
testInfo.Result.EndTime = endTime;
testInfo.Result.Duration = duration;
testInfo.Result.Error = error;
TestResults.Add(testInfo.Result);
// This part must be threadsafe...
if (lvResults.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(ExecuteTest);
this.Invoke(d, new object[] { tInfo });
}
else
{
lvResults.Items.Add(testInfo.Result.ConvertToListViewItem());
#region Update Results - This wouldn't work in it's own method in the threaded version
const string msPrefix = "ms";
// ShortestRun
TimeSpan shortest = GetShortestRun(RunTimes);
tbShortestRun.Text = shortest.TotalMilliseconds + msPrefix;
// AverageRun
TimeSpan average = GetAverageRun(RunTimes);
tbAverageRun.Text = average.TotalMilliseconds + msPrefix;
// MeanRun
TimeSpan mean = GetMeanRun(RunTimes);
tbMeanRun.Text = mean.TotalMilliseconds + msPrefix;
// LongestRun
TimeSpan longest = GetLongestRun(RunTimes);
tbLongestRun.Text = longest.TotalMilliseconds + msPrefix;
// ErrorCount
int errorCount = GetErrorCount(TestResults);
tbErrorCount.Text = errorCount.ToString();
#endregion
}
testInfo.Command.Dispose();
Application.DoEvents();
}
}
Can you post a snippet of run ()? Doesn't Thread.currentThread().notifyAll() help? May be each thread is waiting for other thread to do something resulting in a deadlock?