while (1 == 1)
{
int questions = 0;
Thread.Sleep(500);
try
{
driver.FindElement(By.XPath("//*[#id='root']/div/main/div[2]/div/div[1]/button[1]"));
questions++;
}
catch (Exception e)
{
return;
}
try
{
driver.FindElement(By.XPath("//*[#id='root']/div/main/div[2]/div/div[1]/button[2]"));
questions++;
}
catch (Exception e)
{
return;
}
try
{
driver.FindElement(By.XPath("//*[#id='root']/div/main/div[2]/div/div[1]/button[3]"));
questions++;
}
catch (Exception e)
{
return;
}
try
{
driver.FindElement(By.XPath("//*[#id='root']/div/main/div[2]/div/div[1]/button[4]"));
questions++;
}
catch (Exception e)
{
return;
}
if (questions == 0)
{
return;
}
else if (questions == 1)
{
MessageBox.Show("1", "1");
driver.FindElement(By.XPath("//*[#id='root']/div/main/div[2]/div/div[1]/button[1]")).Click();
}
else if (questions == 2)
{
MessageBox.Show("2", "2");
String[] av2 = { "//*[#id='root']/div/main/div[2]/div/div[1]/button[1]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[2]"};
Random random = new Random();
int a = random.Next(av2.Length);
driver.FindElement(By.XPath(av2[a])).Click();
}
else if (questions == 3)
{
MessageBox.Show("3", "3");
String[] av3 =
{
"//*[#id='root']/div/main/div[2]/div/div[1]/button[1]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[2]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[3]"
};
Random random = new Random();
int a = random.Next(av3.Length);
driver.FindElement(By.XPath(av3[a])).Click();
}
else if (questions == 4)
{
MessageBox.Show("4", "4");
String[] av4 =
{
"//*[#id='root']/div/main/div[2]/div/div[1]/button[1]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[2]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[3]",
"//*[#id='root']/div/main/div[2]/div/div[1]/button[4]"
};
Random random = new Random();
int a = random.Next(av4.Length);
driver.FindElement(By.XPath(av4[a])).Click();
}
Console.WriteLine(questions + " <");
}
I'm not experienced at all, and don't know why this class keeps exiting with code 0. I've tried multiple things, but none worked. So, what I am trying to have it do is have this piece of C# code check for an xpath with selenium every .5 seconds. but as it is right now, it exits with exit code 0. How can i fix this?
return statement, if placed in the Main function, stops execution of the program. Move your code to function, and add some logic to prevent console application from closing
using System;
namespace ConsoleApp7
{
class Program
{
static void Main(string[] args)
{
DoYourThings();
Console.WriteLine("Press any key to close application...");
Console.ReadKey(); // application hangs here until user clicks any button,
// so you have time to examine console window
}
static void DoYourThings()
{
while (true)
{
try
{
// some code
}
catch (Exception e)
{
Console.WriteLine(e.Message); // output exception message
return; // exits DoYourThings function
}
}
}
}
}
It appears that you want to select a random item from several XPaths (if found) and click it. The problem is that instead of ignoring exceptions (by not doing anything) you're calling return;, which will exit the method.
Instead, you can just remove the return statement from inside your catch blocks, and that should resolve your issue.
Additionally, you seem to have a lot of repeated code which can be simplified if we store some of the results in lists and then loop over those lists (and choose a random element from a list). Also, you only need to initialize the instance of Random once.
For example:
// Only initialize random one time
var random = new Random();
// Store our XPaths in a list so we can loop over them
var buttonXPaths = new List<string>
{
$"//*[#id='root']/div/main/div[2]/div/div[1]/button[1]",
$"//*[#id='root']/div/main/div[2]/div/div[1]/button[2]",
$"//*[#id='root']/div/main/div[2]/div/div[1]/button[3]",
$"//*[#id='root']/div/main/div[2]/div/div[1]/button[4]",
};
// Endless loop
while (true)
{
// Sleep for half a second
Thread.Sleep(500);
// Create a list to hold any WebElements we find
var elements = new List<WebElement>();
// For each XPath, try to find the element and add it to our list
foreach (var buttonXPath in buttonXPaths)
{
try
{
elements.Add(driver.FindElement(buttonXPath));
}
catch
{
// Ignore any exceptions. The next line isn't necessary, but I
// included it so you can see the syntax for explicitly skipping
// a loop iteration and starting it over again (you were using 'return')
continue;
}
}
// If we found any elements. This is the same as: if (elements.Count > 0)
if (elements.Any())
{
// Display the number of elements found in a message box
MessageBox.Show(elements.Count.ToString(), elements.Count.ToString());
// Choose a random element from our list
WebElement randomElement = elements[random.Next(elements.Count)];
// Click it
randomElement.Click();
// This was in your code, not sure why
Console.WriteLine($"{elements.Count} <");
}
}
Related
I am developing a C# Windows Form program in which there are a number of called Methods (what in VB I called Subs). Excuse me if I'm using the wrong terms, new to C#. One of these methods is being ignored, CreateFolder(). When I set break points to debug and step through, the program gets to the called method and goes right through it like it like it was a blank line, no errors warning just goes through. The program is a bit large so I'm including what I hope is helpful. Sorry if too much. The method (sub) not being executed is CreateFolder(). Again, the debugger will stop on this line[CreateFolder()] in the ProcessEmail() routine but just goes on without going to the called code. Thoughts?
public partial class FrmProcessNew : Form
{
...bunch of global vaiables
private void FrmProcessNew_Load(object sender, EventArgs e)
{
chkBoxTesting.Checked = Convert.ToBoolean(ConfigurationManager.AppSettings["testing"]); //check if test to ignore bad credit cards
}
private void btnStart_Click(object sender, EventArgs e)
{
ProcessEmail(); //check for, process and then move new Outlook emails
}
public void ScrollBox(string box) //try to get scroll box right
{
if (box == "Text")
{
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
}
if (box == "List")
{ listBox1.TopIndex = listBox1.Items.Count - 1; }
}
public static int GetLineNumber(COMException ex) //Get the line number if an error occurs - from stack overflow
{
var lineNumber = 0;
const string lineSearch = ":line ";
var index = ex.StackTrace.LastIndexOf(lineSearch);
if (index != -1)
{
var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
if (int.TryParse(lineNumberText, out lineNumber))
{
}
}
return lineNumber;
}
private void ProcessEmail() // Process the new email
{
while (inboxFolder.Items.Count == 0) //check for any email in Inbox
{
textBox1.Text = textBox1.Text + ("Inbox is empty - Listening for New emails!\r\n");
ScrollBox("Text");
textBox1.Update();
Delay(); //wait 5 seconds
}
CreateFolder(); //Create new destination folder to move processed emails to - NOT FORWARDING TO THIS SUB!!
try
{
foreach (Microsoft.Office.Interop.Outlook.MailItem mailItem in inboxFolder.Items)
{
....processing stuff
}
catch (System.Runtime.InteropServices.COMException ex)
{
....capture error
}
finally
{
....reset stuff
}
}
public void CreateFolder() //Create Outlook Folders to store processed emails = NEVER GETS TO THIS CODE!!!
{
DateTime fldDate = DateTime.Now;
if (fldDate.DayOfWeek != DayOfWeek.Friday) //must process with a Friday date, set date to next Friday
{
fldDate = NextFriday(fldDate);
}
String myYear = fldDate.ToString("yyyy");
string myMonth = fldDate.ToString("MM");
string myDay = fldDate.ToString("dd"); //day of the month
string fileDate = (myYear.ToString()) + "-" + (myMonth.ToString()) + "-" + myDay; // build the Date for Destination "file";
try
{olDestinationFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)]; }
catch
{ olDestinationFolder = ns.Folders[mailBoxName].Folders[("done")].Folders.Add(fileDate); }
try
{ olBadCreditFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders[("BadCredit")]; }
catch
{ olBadCreditFolder = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders.Add("BadCredit"); }
try
{ olNonOrderEmails = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders[("Non-OrderEmails")]; }
catch
{ olNonOrderEmails = ns.Folders[mailBoxName].Folders[("done")].Folders[(fileDate)].Folders.Add("Non-OrderEmails"); }
}
private void Delay() //If no emails then want 5 seconds and try again
{
textBox1.Text = textBox1.Text + ("Inbox is empty - Listening for New emails!\r\n");
ScrollBox("Text");
textBox1.Update();
// await Task.Delay(5000); //Wait 5 seconds for new email
var t = Task.Run(async delegate
{
await Task.Delay(TimeSpan.FromSeconds(5.5));
ScrollBox("Text");
return 42;
});
}
static DateTime NextFriday(DateTime fldDate) //Find the next FRIDAY date.
{
do
{
fldDate = fldDate.AddDays(1);
}
while (fldDate.DayOfWeek != DayOfWeek.Friday);
return fldDate;
}
}
}
I have a class that executes my function but the variable changes too fast for me to even append my file. I need the speed but I need the functionality in my multithreading. Here's what's in my program.cs that's really the main key in multithreading.
process process = new process();
Thread[] threads = new Thread[15];
static int refInt = 0;
for (int i = 0; i < threads.Count(); i++)
{
threads[i] = new Thread(process.checkCookies);
}
foreach (Thread threadStart in threads)
{
threadStart.Start();
}
That's my program.cs and here's my process library.
public void checkCookies()
{
try
{
while (Interlocked.Increment(ref refInt) < cookies.Count)
{
try
{
string data = functions.cookieToUserId(cookies[refInt]);
if (data == "The cookie is incorrect.")
{
ConsoleWrite("\nThe cookie is invalid.", ConsoleColor.DarkRed);
continue;
}
string cookiesValue = functions.getRobux(cookies[refInt]);
if (cookiesValue == "Invalid cookie.")
{
ConsoleWrite("\nThe cookie is invalid.", ConsoleColor.DarkRed);
continue;
}
else if (Convert.ToInt32(cookiesValue) < 5)
{
ConsoleWrite(string.Format("\nThe account has less than 5 currency. [{0}]", data), ConsoleColor.DarkRed);
continue;
}
else if (Convert.ToInt32(cookiesValue) > 5)
{
ConsoleWrite(string.Format("\nThe account has {0} currency. [{1}]", cookiesValue, data), ConsoleColor.DarkGreen);
functions.appendFile("config/checkedCookies.txt", cookies[refInt]);
continue;
}
}
catch
{
//exception
}
}
}
catch
{
//exception
}
}
My issue is that whenever there is a cookie with a currency integer greater than 5, when it appendsFile which is basically this function here.
public string appendFile(string file, string content)
{
try
{
using (StreamWriter writeStream = File.AppendText(file))
{
writeStream.WriteLine(content);
return "Appended the text successfully!";
}
}
catch (Exception)
{
return "Error appending the text.";
}
}
The refInt changes due to another thread running it. So if refInt is equal to 4, then after it goes through all the else if statements. The refInt changes to 20-25 because of the other threads running the code and changing the global variable so whenever I append text, it appends the wrong cookie. What are some methods to make it so the global variable doesn't get changed too fast, by the way. I need the speed to be as fast as that.
i dont know if its helps or kills ur multithreading idee but did u ever think about mutex lock?
https://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/
i have a trouble terminating a void function in C#, i tried to put all the function body in a try and created catch body to throw nothing but termination, my question Is this method the best to terminate void function, Or you have another better solution?
Code Below
public void funCall(string element, TreeNode tree){
try
{
string[] constraintsOfFunction = { };
try
{
constraintsOfFunction = splitter(symbol[element].Key.ToString());
}
catch (Exception e)
{
errorHandler(3);
}
string paramsCount = constraintsOfFunction[0];
foreach (var x in tree.Nodes)
{
MessageBox.Show(x.ToString());
}
for (int i = 1; i <= Convert.ToInt32(paramsCount); i++)
{
MessageBox.Show(constraintsOfFunction[i]);
}
}
catch (Exception e)
{ }
}
You can do so by adding this line:
return;
For foreach, for, and while loops, you must use the following to exit the loop:
break;
Have you tried a finally{} for the try catch? Ultimately, you just need to return;
I am using a for loop for making Calls for a list of numbers.
I want to take the first number from the list and make a call and to wait for the response and then proceed to the next number in the list.
I have used AutoResetEvent to do this.But it is not working.
for (int k = 0; k < list_Items.Count; k++) {
Number_To_Call = "9" + list_Items[k].ToString();
phoneCall.Start();
waitingToPickUp.Set(); //AutoReset Event
Thread.Sleep();
waitingToPickUp.WaitOne();
string detector = VoiceDetected;
if (detector == "Machine") {
//code
} else if (detector == "Human") {
//code
} else {
//code
}
}
Code for getting response form the call
void phoneCall_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
{
if (e.Item.IsInCall())
{
phoneCallAudioReceiver.AttachToCall(phoneCall);
phoneCallAudioSender.AttachToCall(phoneCall);
manchineDetector.Start();
waitingToPickUp.Set();
string str = VoiceDetected;
}
else if (e.Item.IsCallEnded())
{
phoneCallAudioReceiver.Detach();
phoneCallAudioSender.Detach();
manchineDetector.Stop();
phoneCall = null;
//Number_To_Call = string.Empty;
InvokeOnGUIThread(() =>
{
Number_To_Call = string.Empty;
});
}
}
Code for Detecting Machine or Human
void manchineDetector_DetectionCompleted(object sender, VoIPEventArgs<AnswerMachineDetectionResult> e)
{
try
{
string VoiceDetected = e.Item.ToString();
}
catch (Exception ex)
{
}
}
Set and immediately WaitOne makes no sense - wait will not need to wait for anything and immediately continue.
Most likely should be reset-call-wait:
waitingToPickUp.Reset();
phoneCall.Start();
waitingToPickUp.WaitOne();
I am breaking a list into chunks and processing it as below:
foreach (var partialist in breaklistinchunks(chunksize))
{
try
{
do something
}
catch
{
print error
}
}
public static class IEnumerableExtensions
{
public static IEnumerable<List<T>> BreakListinChunks<T>(this IEnumerable<T> sourceList, int chunkSize)
{
List<T> chunkReturn = new List<T>(chunkSize);
foreach (var item in sourceList)
{
chunkReturn.Add(item);
if (chunkReturn.Count == chunkSize)
{
yield return chunkReturn;
chunkReturn = new List<T>(chunkSize);
}
}
if (chunkReturn.Any())
{
yield return chunkReturn;
}
}
}
If there is an error, I wish to run the chunk again. Is it possible to find the particular chunk number where we received the error and run that again ?
The batches have to be executed in sequential order .So if batch#2 generates an error, then I need to be able to run 2 again, if it fails again. I just need to get out of the loop for good .
List<Chunk> failedChunks = new List<Chunk>();
foreach (var partialist in breaklistinchunks(chunksize))
{
try
{
//do something
}
catch
{
//print error
failedChunks.Add(partiallist);
}
}
// attempt to re-process failed chunks here
I propose this answer based on your comment to Aaron's answer.
The batches have to be executed in sequential order .So if 2 is a problem , then I need to be able to run 2 again, if it fails again. I just need to get out of the loop for good.
foreach (var partialist in breaklistinchunks(chunksize))
{
int fails = 0;
bool success = false;
do
{
try
{
// do your action
success = true; // should be on the last line before the 'catch'
}
catch
{
fails += 1;
// do something about error before running again
}
}while (!success && fails < 2);
// exit the iteration if not successful and fails is 2
if (!success && fails >= 2)
break;
}
I made a possible solution for you if you don't mind switching from Enumerable to Queue, which kind of fits given the requirements...
void Main()
{
var list = new Queue<int>();
list.Enqueue(1);
list.Enqueue(2);
list.Enqueue(3);
list.Enqueue(4);
list.Enqueue(5);
var random = new Random();
int chunksize = 2;
foreach (var chunk in list.BreakListinChunks(chunksize))
{
foreach (var item in chunk)
{
try
{
if(random.Next(0, 3) == 0) // 1 in 3 chance of error
throw new Exception(item + " is a problem");
else
Console.WriteLine (item + " is OK");
}
catch (Exception ex)
{
Console.WriteLine (ex.Message);
list.Enqueue(item);
}
}
}
}
public static class IEnumerableExtensions
{
public static IEnumerable<List<T>> BreakListinChunks<T>(this Queue<T> sourceList, int chunkSize)
{
List<T> chunkReturn = new List<T>(chunkSize);
while(sourceList.Count > 0)
{
chunkReturn.Add(sourceList.Dequeue());
if (chunkReturn.Count == chunkSize || sourceList.Count == 0)
{
yield return chunkReturn;
chunkReturn = new List<T>(chunkSize);
}
}
}
}
Outputs
1 is a problem
2 is OK
3 is a problem
4 is a problem
5 is a problem
1 is a problem
3 is OK
4 is OK
5 is OK
1 is a problem
1 is OK
One possibility would be to use a for loop instead of a foreach loop and use the counter as a means to determine where an error occurred. Then you could continue from where you left off.
You can use break to exit out of the loop as soon as a chunk fails twice:
foreach (var partialList in breaklistinchunks(chunksize))
{
if(!TryOperation(partialList) && !TryOperation(partialList))
{
break;
}
}
private bool TryOperation<T>(List<T> list)
{
try
{
// do something
}
catch
{
// print error
return false;
}
return true;
}
You could even make the loop into a one-liner with LINQ, but it is generally bad practice to combine LINQ with side-effects, and it's not very readable:
breaklistinchunks(chunksize).TakeWhile(x => TryOperation(x) || TryOperation(x));