Adding Try and Catch to existing program - c#-4.0

Good Evening all,
In a little of a pickle with a huge brain fart and could use a little help with something. So i wrote this C# console app that uses Selenium to open a web page, logs in, does some stuff, then submit a form and logs off the site. Now I have this in a for loop to do it 100 times. Now very rarely it may hiccup and throws an exception cause page didn't load fast enough or something. I thought it may be good to use a try/catch but once as the catch catches the exception, but I want it to redo that loop number that it is on and continue on. So example, say if i am on iteration 66 of 100 and it throws an exception cause page didn't load fast enough or there was an error on the page for that link, i need it to catch it, log it, then restart at number 66 again. Below is some of my original code and another section of what i have gotten it to.
using System;
using System.Collections.Generic;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System.Threading;
using System.IO;
namespace SeleniumTest
{
class Program
{
static void Main(string[] args)
{
for (Int64 i = 1; i < 100; i++)
{
DateTime time;
time = DateTime.Now;
StreamWriter tw = new StreamWriter(#"C:\folder\file.txt", true);
IWebDriver driver = new FirefoxDriver();
tw.WriteLine("Staring test," + time);
driver.Navigate().GoToUrl("http://site.com");
driver.FindElement(By.Name("username")).Clear();
driver.FindElement(By.Name("username")).SendKeys("username");
driver.FindElement(By.Name("password")).Clear();
driver.FindElement(By.Name("password")).SendKeys("password");
driver.FindElement(By.CssSelector("input.ui-standard-button")).Click();
driver.FindElement(By.LinkText("page")).Click();
driver.FindElement(By.LinkText("page")).Click();
Thread.Sleep(5000);
//Do awesome stuff
DateTime time1;
time1 = DateTime.Now;
driver.FindElement(By.CssSelector("div.Parameters")).Click();
driver.FindElement(By.Name("submit")).Click();
driver.FindElement(By.LinkText("Logoff")).Click();
driver.Quit();
tw.WriteLine("Stopping Test Successfully," + time1);
tw.Flush();
tw.Close();
Thread.Sleep(10000);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System.Threading;
using System.IO;
namespace SeleniumTest
{
class Program
{
static void Main(string[] args)
{
try
{
for (Int64 i = 1; i < 100; i++)
{
DateTime time;
time = DateTime.Now;
StreamWriter tw = new StreamWriter(#"C:\folder\file.txt", true);
IWebDriver driver = new FirefoxDriver();
tw.WriteLine("Staring test," + time);
driver.Navigate().GoToUrl("http://site.com");
driver.FindElement(By.Name("username")).Clear();
driver.FindElement(By.Name("username")).SendKeys("username");
driver.FindElement(By.Name("password")).Clear();
driver.FindElement(By.Name("password")).SendKeys("password");
driver.FindElement(By.CssSelector("input.ui-standard-button")).Click();
driver.FindElement(By.LinkText("page")).Click();
driver.FindElement(By.LinkText("page")).Click();
Thread.Sleep(5000);
//Do awesome stuff
DateTime time1;
time1 = DateTime.Now;
driver.FindElement(By.CssSelector("div.Parameters")).Click();
driver.FindElement(By.Name("submit")).Click();
driver.FindElement(By.LinkText("Logoff")).Click();
driver.Quit();
tw.WriteLine("Stopping Test Successfully," + time1);
tw.Flush();
tw.Close();
Thread.Sleep(10000);
}
}
catch(Exception e)
{
StreamWriter tw = new StreamWriter(#"C:\folder\file.txt", true);
tw.WriteLine("Problem happened. Restarting test. Exception is :" + e);
//Line of code to restart test at number 66 which I don't know
}
}
}
}
Where //Line of code to restart test at number 66 which I don't know is where my knowledge ends and hopefully is where someone else is. Any guidance you can give would be great and appreciated.

Decrementing the counter when an exception is encountered should do it.
for (Int64 i = 1; i < 100; i++) {
try {
//main code here
} catch (Exception ex) {
//logging here
i--;
}
}

I would try to figure out why it's failing, but if that's not an option I would convert it to a while loop with a try catch
int i = 100;
while(i > 0)
{
try
{
//Do your logic here
i--
}
catch
{
//Log failure
}//Don't decrement in case of failure
}

for (Int64 i = 1; i < 100; ++i)
{
for (;;)
{
try
{
//code here
break;
}
catch (Exception exc)
{
//log error
}
}
}

Related

Start test body after jar file loading (from JAVA) is finished

I want to write UNIT test with SOAP webservices. Webservices work in other jar file, which I try to load Runtime.getRuntime().exec(// java - jar ...). Loading jar file takes 2 min. When loading is in new Thread the test ends before loading jar file will be finished. If loading is in main thread, test is not finished. I try to listen HTTP response with while cycle, but when cycle is working, the jar file is not loading.
#Before
public void setUp() throws Exception {
// Get path of jar file
thread = new Thread() {
public void run() {
try {
Process process = Runtime.getRuntime().exec(path-to-java.exe -jar webservices.jar);
process.waitFor();
process.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
int responseCode;
do {
responseCode = getResponseCodeHTTP("http://localhost:8080/services");
} while (responseCode < 200 || responseCode >= 400);
System.out.println("Web services have loaded");
}
public int getResponseCodeHTTP(String urlToRead) throws IOException {
URL url = new URL(urlToRead);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int result;
try {
conn.connect();
result = conn.getResponseCode();
} catch (ConnectException e){
return 500;
}
return result;
}
OK. I want to write test, which will start the webservices from jar file (loading process takes 1.5 min) and then execute test. To start web services I use Runtime.getRuntime().exec and to understand that them started I use HTTP response code. When the code [200-400) , it means the ws started OK.
I tried to debug code inside new Thread and added code with InputStreamReader and while cycle.
String line;
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
while ((line = reader.readLine()) != null)
System.out.println("[Stdout] " + line);
And test successfully executed. The when I removed the while cycle with readline, the problem had repeated.
I have not understand yet why it worked.

c# Serialport data received event handler

I am currently reading data from serialport using WPF. I am able to read data from serialport & write it in File using Binarywriter.
What Problem I am facing right now is:
I want to Analyse this data. I have developed one function which contains Use case structures to split the data which i read in serialport datahandler. Purpose is to Analyse captured data. But my program is just hanging on in receiving data from Serialport. Its not approaching down to Analyse the data.
This are few Options which i read from some Posts which may be a solution for my problem:
Backgroundworker: If yes then how i can fetch in my current program?
Threading: I tried it but its not working. My program is handing on writing the Bytes in the file & not going down to start the thread which i declared.
So can anybody suggest me a better option?
My code:
private void port_DataReceived(Object sender, SerialDataReceivedEventArgs e) {
BinaryWriter writer=new BinaryWriter(File.Open("c:\\temp\\lbus2snifflog1.txt", FileMode.Append));
int bytes=comport.Read(buffer, 0, 4096);
for (int i=0;
i < bytes;
i++) {
//writer.Write(buffer, 0, bytes); // Write the data to the file on temp folder
data.Enqueue(buffer[i]); // Enqueue data from the buffer
writer.Write(buffer, 0, bytes);
}
//writer.Write(buffer, 0, bytes);
writer.Flush(); // Send all remaining data to the writer
writer.Close(); // Close the writer
/*Initilaise the Thread for the Analysis*/
Thread Analyser=new Thread(datacollection);
Analyser.Start();
}
I think you should run thread with setting IsBackground = true;
I use it like that
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
//Do what you want to Run in background here
}).Start();
or maybe simple setting will do the job :
Analyser.IsBackground = true;
Analyser.Start();
Edit
For your case, don't know if this is best approach, but this may work.
You have a ConcurrentDictionary in main thread. In BackgroundWorker thread you get the data from the ConcurrentDictionary. Then you report to main thread the processed data.
Here is a working scenario.
Example:
class MyClass
{
private ConcurrentDictionary<int, string> serialPortsQueue =
new ConcurrentDictionary<int, string>();
private BackgroundWorker _worker;
public MyClass()
{
_worker = new BackgroundWorker()
{
WorkerSupportsCancellation = true,
WorkerReportsProgress = true
};
_worker.DoWork += DeviceDataAcquisition_DoWork;
_worker.ProgressChanged += DeviceDataAcquisition_ProgressChanged;
_worker.RunWorkerCompleted += DeviceDataAcquisition_RunWorkerCompleted;
_worker.RunWorkerAsync();
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: begin add first data");
serialPortsQueue.TryAdd(1, "data 1");
serialPortsQueue.TryAdd(2, "data 2");
serialPortsQueue.TryAdd(3, "data 3");
serialPortsQueue.TryAdd(4, "data 4");
serialPortsQueue.TryAdd(5, "data 5");
serialPortsQueue.TryAdd(6, "data 6");
serialPortsQueue.TryAdd(7, "data 7");
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end add first data");
Thread.Sleep(2000);
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: begin add second data");
serialPortsQueue.TryAdd(8, "data 8");
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end add second data");
}
private void DeviceDataAcquisition_DoWork(object sender, DoWorkEventArgs e)
{
// backgroundworker thread
if (sender is BackgroundWorker worker)
{
//just demo propose
int cnt = 0;
while (true)
{
if (worker.CancellationPending)
break;
if (serialPortsQueue.Count > 0)
{
KeyValuePair<int, string> kv = serialPortsQueue.ElementAt(0);
serialPortsQueue.TryRemove(kv.Key, out string value);
//just demo propose
// Simulate some processing
Thread.Sleep(1000);
worker.ReportProgress(0, kv);
//just demo propose
cnt++;
}
//just demo propose
if (cnt == 8)
break;
}
}
}
private void DeviceDataAcquisition_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// main thread
if (e.UserState is KeyValuePair<int, string> kv)
{
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: {kv.Key} -> {kv.Value}");
}
}
private void DeviceDataAcquisition_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (sender is BackgroundWorker worker)
{
worker.DoWork -= DeviceDataAcquisition_DoWork;
worker.ProgressChanged -= DeviceDataAcquisition_ProgressChanged;
worker.RunWorkerCompleted -= DeviceDataAcquisition_RunWorkerCompleted;
worker.Dispose(); // i think this does nothing...
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end backgroundworker");
}
}
}
You can see in the window Output -> Debug the results.
Hope this helps.

CyclicBarrier code not working?

I got CyclicBarrier code from oracle page to understand it more. I modified it and now having one doubt.
Below code doesn't terminate but If I uncomment Thread.sleep condition, It works fine.
import java.util.Arrays;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Solver {
final int N;
final float[][] data;
boolean done = false;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) {
myRow = row;
}
public void run() {
while (!done) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
System.out.println("Run finish for " + Thread.currentThread().getName());
}
private void processRow(int row) {
float[] rowData = data[row];
for (int i = 0; i < rowData.length; i++) {
rowData[i] = 1;
}
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
done = true;
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
barrier = new CyclicBarrier(N, new Runnable() {
public void run() {
for (int i = 0; i < data.length; i++) {
System.out.println("Data " + Arrays.toString(data[i]));
}
System.out.println("Completed:");
}
});
for (int i = 0; i < N; ++i)
new Thread(new Worker(i), "Thread "+ i).start();
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
float[][] matrix = new float[5][5];
Solver solver = new Solver(matrix);
}
}
Why Thread.sleep is required in above code?
I've not run your code but there may be a race condition, here is a scenario that reveals it:
you start the first thread, it runs during a certain amount of time sufficient for it to finish the processRow method call so it sets done to true and then waits on the barrier,
the other threads start but they see that all is "done" so they don't enter the loop and they'll never wait on the barrier, and end directly
the barrier will never be activated as only one of the N threads has reached it
deadlock
Why it is working with the sleep:
when one of the thread starts to sleep it lets the other threads work before marking the work as "done"
the other threads have enough time to work and can themselves reach the barrier
2 seconds is largely enough for 5 threads to end a processing that should not last longer than 10ms
But note that if your system is ovrerloaded it could too deadlock:
the first thread starts to sleep
the OS scheduler lets another application work during more than 2 seconds
the OS scheduler comes back to your application and the threads scheduler chooses the first thread again and lets it terminate, setting done to true
and here again the first scenario => deadlock too
And a possible solution (sorry not tested):
change your while loops for do/while loops:
do
{
processRow(myRow);
...
}
while (!done);

WP7 - Having trouble gracefully exiting bg thread on app deactivate or closing

My somewhat data-intensive wp7 app persists data as follows: I maintain a change journal reflecting all user activity, and every couple of seconds, a thread timer spins up a threadpool thread that flushes the change journal to a database inside a transaction. It looks something like this:
When the user exits, I stop the timer, flush the journal on the UI thread (takes no more than a second or two), and dismount the DB.
However, if the worker thread is active when the user exits, I can't figure out how to react gracefully. The system seems to kill the worker thread, so it never finishes its work and never gives up its lock on the database connection, and the ui thread then attempts to acquire the lock, and is immediately killed by the system. I tried setting a flag on the UI thread requesting the worker to abort, but I think the worker was interrupted before it read the flag. Everything works fine except for this 1 in 100 scenario where some user changes end up not being saved to the db, and I can't seem to get around this.
Very simplified code below:
private Timer _SweepTimer = new Timer(SweepCallback, null, 5000, 5000);
private volatile bool _BailOut = false;
private void SweepCallback(object state) {
lock (db) {
db.startTransaction();
foreach(var entry in changeJournal){
//CRUD entry as appropriate
if(_BailOut){
db.rollbackTransaction();
return;
}
}
db.endTransaction();
changeJournal.Clear();
}
}
private void RespondToSystemExit(){
_BailOut = true; //Set flag for worker to exit
lock(db){ //In theory, should acquire the lock after the bg thread bails out
SweepCallback(null);//Flush to db on the UI thread
db.dismount();//App is now ready to close
}
}
Well, just to close this question, I ended up using a manualresetevent instead of the locking, which is to the best of my understanding a misuse of the manualresetevent, risky and hacky, but its better than nothing.
I still don't know why my original code wasn't working.
EDIT: For posterity, I'm reposting the code to reproduce this from the MS forums:
//This is a functioning console app showing the code working as it should. Press "w" and then "i" to start and then interrupt the worker
using System;
using System.Threading;
namespace deadlocktest {
class Program {
static void Main(string[] args) {
var tester = new ThreadTest();
string input = "";
while (!input.Equals("x")) {
input = Console.ReadLine();
switch (input) {
case "w":
tester.StartWorker();
break;
case "i":
tester.Interrupt();
break;
default:
return;
}
}
}
}
class ThreadTest{
private Object lockObj = new Object();
private volatile bool WorkerCancel = false;
public void StartWorker(){
ThreadPool.QueueUserWorkItem((obj) => {
if (Monitor.TryEnter(lockObj)) {
try {
Log("Worker acquired the lock");
for (int x = 0; x < 10; x++) {
Thread.Sleep(1200);
Log("Worker: tick" + x.ToString());
if (WorkerCancel) {
Log("Worker received exit signal, exiting");
WorkerCancel = false;
break;
}
}
} finally {
Monitor.Exit(lockObj);
Log("Worker released the lock");
}
} else {
Log("Worker failed to acquire lock");
}
});
}
public void Interrupt() {
Log("UI thread - Setting interrupt flag");
WorkerCancel = true;
if (Monitor.TryEnter(lockObj, 5000)) {
try {
Log("UI thread - successfully acquired lock from worker");
} finally {
Monitor.Exit(lockObj);
Log("UI thread - Released the lock");
}
} else {
Log("UI thread - failed to acquire the lock from the worker");
}
}
private void Log(string Data) {
Console.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString("mm:ss:ffff"), Data));
}
}
}
Here is nearly identical code that fails for WP7, just make a page with two buttons and hook them
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using Microsoft.Phone.Controls;
namespace WorkerThreadDemo {
public partial class MainPage : PhoneApplicationPage {
public MainPage() {
InitializeComponent();
}
private Object lockObj = new Object();
private volatile bool WorkerCancel = false;
private void buttonStartWorker_Click(object sender, RoutedEventArgs e) {
ThreadPool.QueueUserWorkItem((obj) => {
if (Monitor.TryEnter(lockObj)) {
try {
Log("Worker acquired the lock");
for (int x = 0; x < 10; x++) {
Thread.Sleep(1200);
Log("Worker: tick" + x.ToString());
if (WorkerCancel) {
Log("Worker received exit signal, exiting");
WorkerCancel = false;
break;
}
}
} finally {
Monitor.Exit(lockObj);
Log("Worker released the lock");
}
} else {
Log("Worker failed to acquire lock");
}
});
}
private void Log(string Data) {
Debug.WriteLine(string.Format("{0} - {1}", DateTime.Now.ToString("mm:ss:ffff"), Data));
}
private void buttonInterrupt_Click(object sender, RoutedEventArgs e) {
Log("UI thread - Setting interrupt flag");
WorkerCancel = true;
//Thread.Sleep(3000); UNCOMMENT ME AND THIS WILL START TO WORK!
if (Monitor.TryEnter(lockObj, 5000)) {
try {
Log("UI thread - successfully acquired lock from worker");
} finally {
Monitor.Exit(lockObj);
Log("UI thread - Released the lock");
}
} else {
Log("UI thread - failed to acquire the lock from the worker");
}
}
}
}
Your approach should work when you operate from the Application_Deactivated or Application_Closing event. MSDN says:
There is a time limit for the Deactivated event to complete. The
device may terminate the application if it takes longer than 10
seconds to save the transient state.
So if you say it just takes just a few seconds this should be fine. Unless the docs don't tell the whole story. Or your worker thread takes longer to exit than you think.
As Heinrich Ulbricht already said you have <=10 sec to finish your stuff, but you should block MainThread to get them.
It means that even if you have BG thread with much work to do, but your UI thread just does nothing in OnClosingEvent/OnDeactivatingEvent - you will not get your 10 seconds.
Our application actually does eternal wait on UI thread in closing event to allow BG thread send some data thru sockets.

How to grab value from a thread?

Hi i am trying to grab a value from my threading but it seem work not so find to me course i found that my code structure are unstable enough..here is my code i name my thread class as "clsThreadCount" and below is my implementation
public volatile bool Grab = false;
public volatile int count = 0;
public void Initialization(int i)
{
count = i;
}
public void Play()
{
Grab = false;
_shouldStop = false;
ThreadTest();
}
public void Stop()
{
_shouldStop = true;
workerThread.Join(1);
workerThread.Abort();
}
private void ThreadTest()
{
workerThread = new Thread(DoWork);
workerThread.Start();
while (!workerThread.IsAlive) ;
}
private void DoWork()
{
try
{
while (!_shouldStop)
{
if (Grab)
{
count++;
Grab = false;
}
}
}
catch (Exception)
{
Play();
}
finally
{
}
}
when my program(main menu) are starting to run i will trigger the initialize function at pass the parameter as 7
ObjThreadCount.Initialization(7); // count = 7
ObjThreadCount.Play(); // the thread are running
ObjThreadCount.Grab = true; // the grab equal to true, count++ are trigger
Thread.Sleep(100); // wait awhile
lblResult.Text = ObjThreadCount.count.ToString(); // sometime i can get count++ result (e.g. 8)
ObjThreadCount.Stop(); // thread stop
sometime my program can able to get a right counting from the thread but sometime are not.
i realize at my while loop implementation there are something are missing..
something like waitone or waitautoevent..can i ignore Thread.Sleep(100) ?? what are the suitable code should i add in the while loop ?
Please help me~ :S
** sorry in the first upload i forgot to write down "volatile" into the variable
thank you..
If C# (and C and java, and probably C++), you need to declare _shouldStop and Grab as volatile.

Resources