I am trying to get my program to close when clicking a stop button.
I am using a background worker, but whenever i click stop, the form hangs and then i get an error saying "An exception of type 'OpenQA.Selenium.WebDriverException' occurred in WebDriver.dll but was not handled in user code"
My stop button click code is
private void button2_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation)
{
backgroundWorker1.CancelAsync();
}
Application.Exit();
driverGC.Quit();
}
The RunWorkerCompleted is:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("You've cancelled the backgroundworker!");
}
else if (e.Error != null)
{
MessageBox.Show("Error:" + e.Error.Message);
}
else
{
MessageBox.Show("Done!");
}
}
Yes, i have it supporting cancellation. Any thoughts?
Have you tried:
this.Application.Close();
Related
I'm doing a simple login form that will show the login process after they click button. It will verify the user access rights and give true or false.
I got an error on this.Hide();
System.InvalidOperationException: 'Cross-thread operation not valid: Control 'formLogin' accessed from a thread other than the thread it was created on.'
Any help would be greatly appreciated. Thanks!!
private void btnLogin_Click(object sender, EventArgs e)
{
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += bgw_DoWork;
bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;
PBLogin.Style = ProgressBarStyle.Marquee;
PBLogin.MarqueeAnimationSpeed = 50;
bgw.RunWorkerAsync();
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
PBLogin.Style = ProgressBarStyle.Blocks;
PBLogin.MarqueeAnimationSpeed = 0;
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
if (CheckAuthorization())
{
MessageBox.Show("Login Successfully");
TestScript next = new TestScript();
next.Show();
this.Hide();
}
else
{
MessageBox.Show("Login Failed");
}
From a background thread you can't reach the UI, that's what the exception is trying to tell you. In your background thread you should try to focus only on the Authorization logic itself. Try to avoid UI component manipulation.
In the RunWorkerCompleted event you can indeed modify the UI components. So, do the calculation on a dedicated background thread and do the UI manipulation inside the completion event.
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//TODO: Check against e.Error and e.Cancelled before you try to access e.Result
if((bool)e.Result)
{
//UI modification
}
else
{
//UI modification
}
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
var isAuthorized = CheckAuthorization();
e.Result = isAuthorized;
}
I want to close my application from Menu having Exit option and through Window closing And for both I have added prompt message.
But If I called exit then gives prompt message two times because on Exit_Click event after System.Windows.Application.Current.Shutdown(); it goes to ShellWindow_Closing
public partial class SWindow : Window
{
public SWindow()
{
this.Closing += ShellWindow_Closing;
}
private void ShellWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("Any running migration task will be aborted. \nAre you sure you want to exit the application ?",
"Exit Proventeq Migration Acclerator",
MessageBoxButton.YesNo,
MessageBoxImage.Question) == MessageBoxResult.No)
e.Cancel = true;
}
}
private void Exit_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Any running migration task will be aborted. \nAre you sure you want to exit the application ?", "Exit Proventeq Migration Acclerator", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
e.Handled = true;
}
Whenever You press Exit button or You close the application by ALT + F4 or the right-up X (cross) will be pressed, it always come to Your app closure.
Simplier way is to handle BtnMenuExit_Click as App closure. Then by other behaviour - event for Window close to cancel based on result of message box.
public partial class SWindow : Window
{
public SWindow()
{
this.Closing += ShellWindow_Closing;
}
private void ShellWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("Any running migration task will be aborted.\nAre you sure you want to exit the application ?", "Exit Proventeq Migration Acclerator", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
{
e.Cancel = true;
}
}
private void BtnMenuExit_Click(object sender, EventArgs e)
{
this.Close();
}
}
//designer part
public partial class SWindow
{
//other code
private void InitializeComponent()
{
Button BtnMenuExit = new Button();
BtnMenuExit.Click += new EventHandler(BtnMenuExit_Click);
//other styles etc..
}
//other code
}
I am trying to hide default datagridview error dialog.
I put in the code this event handler:
this.dataGridView2.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(dataGridView2_DataError);
private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
//empty so it doesn't show anything
}
But still when i try this and leave datagridview cell empty ( delete everything from it), it show me dialog box with error.
Screenshot of error:
Try to Handle and Cancel the event:
private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = true;
}
Also, subscribe to the event in InitializeComponent()
private void InitializeComponent()
{
//...
this.dataGridView.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.dataGridView2_DataError);
}
try to use this code to handle the event:
private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = true;
}
Try the next code , it's work!
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
try
{
//To handle 'ConstraintException' default error dialog (for example, unique value)
if ((e.Exception) is System.Data.ConstraintException)
{
// ErrorText glyphs show
dataGridView1.Rows[e.RowIndex].ErrorText = "must be unique value";
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "must be unique value";
//...or MessageBox show
MessageBox.Show(e.Exception.Message, "Error ConstraintException",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
//Suppress a ConstraintException
e.ThrowException = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "ERROR: dataGridView1_DataError",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult dResult;
dResult = MessageBox.Show("You have entered: " + textBox1.Text, "Message Box Info", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Information);
label1.Text = "You clicked " + dResult.ToString();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
button1_Click(this, KeyEventArgs.Empty);
}
}
This is my code to see if the enter key was pressed on a text box, and i want it to click the button when the enter key is pressed. I run the program, and nothing happens. Im new to C# as you can tell. Any help or comments would be helpful.
Thank you in advance.
You can use a shared method:
public void SharedMethod()
{
DialogResult dResult;
dResult = MessageBox.Show("You have entered: " + textBox1.Text, "Message Box Info", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Information);
label1.Text = "You clicked " + dResult.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
SharedMethod();
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SharedMethod();
}
}
You should definitely refactor your code the way pcnThird did it, but I recreated your code in an otherwise empty WinForms app and it worked just fine, even with passing KeyEventArgs.Empty.
The way you've got it, the code should run.
I suspect your KeyDown event is not actually attached to textBox1_KeyDown.
Check your properties window at design-time to make sure it's actually attached.
Or temporarily, type the following into your form's constructor:
this.textBox1.KeyDown += new KeyEventHandler(this.textBox1_KeyDown);
I've been trying to follow this MSDN example, and using the code below. However, e.Error is ALWAYS null in RunWorkerCompleted even when an error does occur in SomeMethod();
private void WorkerDoWork(object sender, DoWorkEventArgs e)
{
getMethod = SomeMethod();
}
private void Worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
var result = ModernDialog.ShowMessage("Error occurred.... " +
e.Result, "ErrorTitle", MessageBoxButton.OK);
}
else if (e.Cancelled)
{
}
Else
{
}
}
Can anyone see what I'm doing wrong?
I can get around it by doing the following but I don't really understand why the example in MSDN is not working for me?
private void WorkerDoWork(object sender, DoWorkEventArgs e)
{
try
{
getMethod = SomeMethod();
}
catch(Exception ex)
{
e.Result = ex;
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result is Exception)
{
var result = ModernDialog.ShowMessage("Error occurred.... " + e.Result, "ErrorTitle", MessageBoxButton.OK);
}
//etc
}
Also, using the second method I can't access the .Message from e.Result. For example, in WorkerDoWork I can use ex.Message
Edit: I've setup the worker to create it's own error and I still get e.Error == null. The variable displayed is a bit faint as CTRL+PrtSc makes it fade
I think the problem is your empty exception block in emailWorkerDoWork(). For the result to be an exception you can't catch the exceptions in your background worker.
So something like this should give you the desired result:
private void emailWorkerDoWork(object sender, DoWorkEventArgs e)
{
int value = 1 / int.Parse("0");
}
I found another SO answer that confirms my suspicion and provides a MSFT reference here.