how to cancel thread c# - c#

hey after long research i come up with a way to cancel thread but i face a problem when i cancel thread here is my code first.so for example when i click on button3 while form working its killing the process but it gives me an error (chrome unrechable)
public void test1()
{
var dr = new chromdriver();
dr.navigate().GoToUrl("http://google.com");
if(xx != null)
{
IWebElement emal = dr.FindElement(By.XPath("//[#id=\"Email\"]"));
emal.Sendkeys(email)
}
else{
IWebElement emal = dr.FindElement(By.XPath("//[#id=\"Email\"]"));
emal.Sendkeys(email)
}
}
private void button2_Click(object sender, EventArgs e)
{
thread thr = new thread(test1);
thr.Start();}
private void button3_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcessesByName("chrome");
Process[] array = processes;
for (int i = 0; i < array.Length; i++)
{
Process process = array[i];
process.Kill();
}
Thread thr = new Thread(review);
thr.Abort();
}

You variables are declared in wrong location
private Thread thr = null;
public void test1()
{
var dr = new chromdriver();
dr.navigate().GoToUrl("http://google.com");
if(xx != null)
{
IWebElement emal = dr.FindElement(By.XPath("//[#id=\"Email\"]"));
emal.Sendkeys(email);
}
else
{
IWebElement emal = dr.FindElement(By.XPath("//[#id=\"Email\"]"));
emal.Sendkeys(email);
}
}
private void button2_Click(object sender, EventArgs e)
{
thr = new Thread(test1);
thr.Start();
}
private void button3_Click(object sender, EventArgs e)
{
Process[] processes = Process.GetProcessesByName("chrome");
Process[] array = processes;
for (int i = 0; i < array.Length; i++)
{
Process process = array[i];
process.Kill();
}
thr.Abort();
}

Related

C# Backgroundworker not reporting progress

Going off of this... https://www.codeproject.com/Articles/841751/MultiThreading-Using-a-Background-Worker-Csharp, I'm trying to have my program do some work in the background on a separate BackGroundWorker. The operation works very well with the exception that myWorker_ProgressChanged does not update the label lbl_status_totalFilesNotCurrent.Content when called from within the myWorker_DoWork foreach loop sendingWorker.ReportProgress(cnt); Im not able to figure out why this part isn't working per the codeproject example.
follow up question... Is the background worker the preferred method for this sort of task, or should i be using tasks? https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming. Im starting to get the sense that background worker is deprecated.
private BackgroundWorker myWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
currentUser.name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
lbl_IndProj.MouseEnter += new MouseEventHandler(changeFontColor);
lbl_IndProj.MouseLeave += new MouseEventHandler(resetFontColor);
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
myWorker.ProgressChanged += new ProgressChangedEventHandler(myWorker_ProgressChanged);
myWorker.WorkerReportsProgress = true;
myWorker.WorkerSupportsCancellation = true;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
if (!myWorker.IsBusy)
{
myWorker.RunWorkerAsync(currentIndex);
}
}
protected void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker sendingWorker = (BackgroundWorker)sender;
Index ci = (Index)e.Argument;
int cnt = 0;
foreach (KeyValuePair<int, Project> project in currentIndex.projects)
{
foreach (KeyValuePair<int, IndexedDirectory> directory in project.Value.IndexedDirectories)
{
foreach (KeyValuePair<int, IndexedFile> indexedfile in directory.Value.IndexedFiles)
{
try
{
List<IndexedFile> ood = currentIndex.getOutOfDateIndexedFiles();
if (ood.Contains(indexedfile.Value))
{
cnt++;
indexedfile.Value.extractInfo();
lbl_status.Content = indexedfile.Value.LongName;
sendingWorker.ReportProgress(cnt);
}
}
catch { }
}
}
}
}
protected void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lbl_status_totalFiles.Content = currentIndex.getAllIndexedFiles().Count().ToString();
lbl_status_totalFilesNotCurrent.Content = currentIndex.getOutOfDateIndexedFiles().Count().ToString();
}
protected void myWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int cnt = e.ProgressPercentage;
int report = currentIndex.getOutOfDateIndexedFiles().Count() - cnt;
lbl_status_totalFilesNotCurrent.Content = report.ToString();
}

How to use check a Button in another Button statement? c#

I am having a problem . I want to use if statement to check if a button is clicked. For Example:
public void button1_Click(object sender, EventArgs e)
{
while (1)
{
...
...
...
if (Button2 == clicked)
{
break;
}
}
}
But it's not working like this, because the ".click" can only be on the left side of "+=" or "-=". Any idea how i can check if Button2 is clicked?
the code is loking like this: and i want to check button2 to stop the "programm".
the check for the Button2 is nearly at the end of the code ;)
public void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
int EmFilterPos;
int ExFilterPos;
string String1;
int[] EmLB = new int[126];
int[] ExLB = new int[126];
int LBEmAnzahl = 0;
int LBEmTot = 0;
int LBExAnzahl = 0;
int LBExTot = 0;
UInt32 C_Zyklen;
UInt32 Zyklen;
Roche.DetectionControl2.Device_Filterwheels.ELBPowerState LB_On = Roche.DetectionControl2.Device_Filterwheels.ELBPowerState.LBOn;
Roche.DetectionControl2.Device_Filterwheels.ELBPowerState LB_Off = Roche.DetectionControl2.Device_Filterwheels.ELBPowerState.LBOff;
Roche.DetectionControl2.Device_Filterwheels.fiweGetLBResponse LightBarrier;
string Text = String.Format("Filterrad-Dauertest\r\nGestart am {0:d} um {0:t}\r\n\r\n", DateTime.Now);
System.IO.File.WriteAllText(#"TestLogFile\Filterrad_Dauertest1.txt", Text);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweInitFilter();
System.Threading.Thread.Sleep(50);
while (Zyklen <= 20)
{
for (int q=1;q<8;q++)
{
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweMove(q,q);
System.Threading.Thread.Sleep(50);
Zyklen++;
}
for (int w=0;w<7;w++)
{
ExFilterPos = rnd.Next(1,8);
EmFilterPos = rnd.Next(1,8);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweMove(ExFilterPos,EmFilterPos);
System.Threading.Thread.Sleep(50);
Zyklen++;
}
C_Zyklen = Zyklen;
if ((C_Zyklen % 2) < 14)
{
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweInitFilter();
System.Threading.Thread.Sleep(50);
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Init bei: ");
String1 = String.Format("{0,7}",Zyklen);
file.Write(String1);
file.Write(file.NewLine);
}
ExFilterPos = 60;
EmFilterPos = 60;
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweRawMove(ExFilterPos,EmFilterPos);
System.Threading.Thread.Sleep(50);
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweSetLB(LB_On);
while (EmFilterPos != -60)
{
LightBarrier = Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweGetLB();
if (LightBarrier.LBEm == Roche.DetectionControl2.Device_Filterwheels.ELBState.LBbright)
{
LBEmAnzahl++;
LBEmTot += EmFilterPos;
}
if (LightBarrier.LBEx == Roche.DetectionControl2.Device_Filterwheels.ELBState.LBbright)
{
LBExAnzahl++;
LBExTot += ExFilterPos;
}
ExFilterPos--;
EmFilterPos--;
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweRawMove(ExFilterPos,EmFilterPos);
}
EmFilterPos = LBEmTot / LBEmAnzahl;
ExFilterPos = LBExTot / LBExAnzahl;
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Nullstelle Mittelposition Em-Filter: ");
file.Write(EmFilterPos);
file.Write(file.NewLine);
file.Write("Nullstelle Mittelposition Ex-Filter: ");
file.Write(ExFilterPos);
file.Write(file.NewLine);
file.Write(file.NewLine);
}
Instrument.N1_DetectionControl2_1_Device_Filterwheels.fiweSetLB(LB_Off);
}
if (Button2 == clicked) // or something like this
break;
}
using (System.IO.StreamWriter file = new System.IO.StreamWriter (#"TestLogFile\Filterrad_Dauertest1.txt", true))
{
file.Write("Beendet am {0:d} um {0:t}\r\n", DateTime.Now);
}*/
}
Hm...
bool b1clicked = false, b2clicked = false;
public void button2_Click(object sender, EventArgs e)
{
b2clicked = true;
}
public void button1_Click(object sender, EventArgs e)
{
b1clicked = true;
if (b1clicked && b2clicked)
{
//...
}
}
Beside the weird behavior you want..and since you are not using Threads, you have the following options:
Local functions (.Net > 4.7)
private void B_Click(object sender, EventArgs e)
{
bool clickFlag = false;
void Click(object sender2, EventArgs e2)
{
clickFlag = true;
}
b2.Click += Click;
while (!clickFlag)
{
Thread.Sleep(1);
}
b2.Click -= Click;
//Continue with your stuff
}
Threads
Thread newThread;
private void Button1_Click()
{
newThread = new Thread(YourBreakableProcess);
newThread.Start();
}
private void Button2_Click()
{
newThread.Join();
}
private void YourBreakableProcess()
{
//Your breakable process
}
Async methods.
I hope you find a solution. Cheers.
Edit:
Since what you want is to interrupt the process of whatever you are doing, the only option you have is Local fuctions as shown above, if you are not tied to a specific framework version.
BackgroundWorker and check in every step if the button 2 was pressed with the flag thing mentioned in other answer.
Threads, and make a thread.Join when the button 2 is pressed.
Edit 2:
Updated answer with Threads, I will recommend that if you go with this option it is much better to use a BackgroundWorker instead as you will have the whole control of the process breaking it only in the place where it would be fine to break it.
You can achieve this using a flag variable. Declare and initialize flag value to false.On button2 click change flag value to true as follows,
private bool flag= false;
private void button2_Click(object sender, EventArgs e)
{
flag= true;
}
public void button1_Click(object sender, EventArgs e)
{
//Use flag to check whether button 2 has clicked or not
if (flag)
{
}
else
{
}
}

Asynchronous Displaying in Windows Form Application c#

I don't think the following question is rarely seen. But since I don't know how to search for the right answer, so I'm still stuck on it.
I have a label in the form and I want to show some words simultaneously
public string[] words = new string[]{"add", "ado", "age", "ago", "aid", "ail", "aim", "air", "and", "any", "ape", "apt", "arc", "are", "ark", "arm",
"art", "ash", "ask", "auk", "awe", "awl", "aye", "bad", "bag", "ban", "bat", "bee", "boa", "ear", "eel", "eft",
"far", "fat", "fit", "lee", "oaf", "rat", "tar", "tie"};
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 39; i++)
{
label1.Text = words[i];
Thread.Sleep(100);
}
}
The label just show "eft" and won't show anything before "for" is complete.
Ideally you should be using a System.Windows.Forms.Timer to update - otherwise you are blocking the main thread. However, you can call Form.Refresh to force an update in your loop.
You may use Task.Delay that would not block the UI thread:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
for (var i = 0; i <= 100; i++)
{
((Button) sender).Content = i.ToString();
await Task.Delay(100);
}
}
Using this solution would not require any extra threads to be created, so it should be more efficient.
Try this
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
label1.Text = i.ToString();
await Task.Run(() => { Thread.Sleep(100); });
}
}
This will work
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 100; i++)
{
Application.DoEvents();
label1.Text = i.ToString();
Thread.Sleep(100);
}
}
call Application.DoEvents() in your code, so your app can handle the other events
You can use System.Threading.Timer:
System.Threading.Timer timer;
int i=-1;
public string[] words = new string[]{"add", "ado", "age", "ago", "aid", "ail", "aim", "air", "and", "any", "ape", "apt", "arc", "are", "ark", "arm",
"art", "ash", "ask", "auk", "awe", "awl", "aye", "bad", "bag", "ban", "bat", "bee", "boa", "ear", "eel", "eft",
"far", "fat", "fit", "lee", "oaf", "rat", "tar", "tie"};
private async void button1_Click(object sender, EventArgs e)
{
timer = new System.Threading.Timer(timer_Tick, null, 0, 100); //Time delay 100
}
private void timer_Tick(Object state)
{
try
{
i++;
this.Invoke((MethodInvoker)delegate
{
label1.Text = words[i];
if (i==words.Length )
timer.Change(Timeout.Infinite, Timeout.Infinite);
});
}
catch (Exception ex)
{
}
finally
{
}
}
ThreadStart safir ;
Thread Nakh;
delegate void kar(string p);
private void button1_Click(object sender, EventArgs e)
{
safir = new ThreadStart(NeveshtanDarBarchasb);
Nakh = Thread(safir);
Nakh.Start();
}
public void NeveshtanDarBarchasb()
{
for (int i = 0; i <= 39; i++)
{
Benevis(I.ToString());
Thread.Sleep(100);
}
}
public void Benevis(string p)
{
if( lbl.InvokeRequired)
{
kar k= new kar(Benevis);
Invoke(k,new object[]{p};
}
else
{
label1.Text = p;
}
}

Problems of while(true) in C# "VS2012" {WinForm}

" int ans = 2;
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i <21; i++)
{
ans = 2;
label1.Text += i.ToString();
while (true)
{
if (ans == 1)
{
break;
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
ans = 1;
} "
this is a simple app
I want to print a number & then wait to the button to be clicked to break the while loop
but when I run the application , the form doesn't show .
"T think that the problem is the while (true)".
what to do?
Use a timer. Start the timer when the form loads. Each time it ticks, increment the number and display it. On button click, you just need to stop the timer.
private Timer _myTimer;
private int number = 0;
private void Form1_Load(object sender, EventArgs e)
{
_myTimer = new Timer();
_myTimer.Interval = 1; // 1 millisecond
_myTimer.Tick += new EventHandler(MyTimer_Tick);
_myTimer.Start();
}
// increments the number at timer tick
private void MyTimer_Tick(object sender, EventArgs e)
{
number ++;
// TODO: update UI here
}
// Stops the timer
private void button1_Click(object sender, EventArgs e)
{
_myTimer.Stop();
}
It's best to not use a loop here. Since this loop won't end you won't ever leave Form_Load and it won't display the form. If you were trying to do some task when the user clicks a button, why not move that logic to button1_Click?
The correct way to implement such a task as you describe would be as such:
private EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
private void Form1_Load(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
for (int i = 0; i < 26; i++)
{
ewh.WaitOne();
Action updateLable = () => label1.Text = "" + i;
label1.BeginInvoke(updateLable);
}
});
}
private void button1_Click(object sender, EventArgs e)
{
ewh.Set();
}
As you can see I've replaced your busy wait (while(true)) with a .Net wait handle.
One of the answers describes a timer that acts every millisecond - that is a busy wait of sorts.
This is what async/await is for. Mark your Load() event with "async", then "await" a Task that continues when a ManualResetEvent is triggered in the Button click handler:
private System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false);
private async void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 21; i++)
{
label1.Text = i.ToString();
mre.Reset();
await Task.Factory.StartNew(() => { mre.WaitOne(); });
}
button1.Enabled = false;
label1.Text = "Done!";
}
private void button1_Click(object sender, EventArgs e)
{
mre.Set();
}

how to make row flash every 3 seconds

I dont know if I'm doing this correctly but I have a grid and I loop through the grid to see if the items matched. If they do I want to make the row flash every 3 seconds. Right now what I have in my code just pretty much highlight the row but no flashing. Can anyone help take a look?
public static void CheckRow(int item, DataGridViewRow row)
{
List<int> col = new List<int>();
//call to db and add to col
foreach (var item in col)
{
if (item == col.Item)
{
currentRow = row;
Timer t = new Timer();
t.Interval = 3000;
t.Tick += new System.EventHandler(Highlight);
t.Start();
}
}
}
private static void Highlight(object sender, EventArgs e)
{
currentRow.DefaultCellStyle.BackColor = Color.Brown;
}
Wouldn't you need to change the color again (to the original) to have a flashing effect?
You should use Threading. Look at the code :)
bool go = false; //for changing cell color
int count = 10; //to stop timer (blinking)
public blinkForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
Thread a = new Thread(blink);
a.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.AutoGenerateColumns = false;
if (dataGridView1.Columns.Count == 0)
{
//generate new columns for DataGridView
dataGridView1.Columns.Add("user", "User");
dataGridView1.Columns.Add("pcStatus", "PC Status");
dataGridView1.Columns.Add("service", "Servis");
//generate new rows for DataGridView
dataGridView1.Rows.Add("Ali", "PC007", "chrome.exe");
dataGridView1.Rows.Add("Vusal", "PC010", "photoshop.exe");
dataGridView1.Rows.Add("Rahim", "PC015", "chrome.exe");
}
}
private void blink(object o)
{
while (count > 0)
{
while (!go)
{
//change color for binking
dataGridView1.Rows[0].Cells["service"].Style.BackColor = Color.Tomato;
go = true;
//stop for 0.5 second
Thread.Sleep(500);
}
while (go)
{
//change color for binking
dataGridView1.Rows[0].Cells["service"].Style.BackColor = Color.LimeGreen;
go = false;
//stop for 0.5 second
Thread.Sleep(500);
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count--;
if (count == 0)
{
//stop blinking after 10 second
timer1.Stop();
}
}
Perhaps this, no?
private static void Highlight(object sender, EventArgs e)
{
currentRow.DefaultCellStyle.BackColor = Color.Brown;
System.Threading.Thread.Sleep(2000);
currentRow.DefaultCellStyle.BackColor = Color.White;
}

Categories