FormClosing, OnFormClosed, ETC... Not firing on ( X ) C# - c#

Alright, so I've got this program I'm trying to write. No company is going to rely on it or anything, so I'm not too caring that the threading here is almost positively poor practice.
My issue is that none of the "Form Closing Events" that I have found on this site and on MSDN are firing for me.
In my code, I have very hopeful console outputs that will notify me if the code has been run, but none of the events that I've found do such.
Can someone slap me into the reality of what it takes to get this to work? I know I must me missing something simple here.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
namespace CMDRunner
{
public partial class Form1 : Form
{
IDataObject clippy = Clipboard.GetDataObject();
String TClippy;
bool isRunning = true;
//Thread worker;
public Form1()
{
InitializeComponent();
try
{
TClippy = Clipboard.GetText();
}
catch (Exception e)
{
richTextBox1.Text += e.ToString() + "\n";
}
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Tick += OnTimerTick;
timer.Interval = 500;
timer.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
//worker = new Thread(KeyChecker);
//worker.SetApartmentState(ApartmentState.STA);
CheckForIllegalCrossThreadCalls = false;
//worker.Start();
System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();
ToolTip1.SetToolTip(this.checkBox1, "Hides anything you run.");
richTextBox2.Text += Clipboard.GetText();
}
void KeyChecker()
{
while (isRunning)
{
Thread.Sleep(40);
if ((Keyboard.GetKeyStates(Key.Return) & KeyStates.Down) > 0)
{
richTextBox1.Text += "Enter Key Clicked!!!\n";
Console.WriteLine(isRunning);
}
}
}
private void OnTimerTick(object sender, EventArgs e)
{
// I will fire the events here
if (Clipboard.ContainsText() == true && TClippy != Clipboard.GetText())
{
try
{
TClippy = Clipboard.GetText();
Clipboard.GetImage();
richTextBox2.Text = TClippy;
richTextBox3.Text = TClippy + "\n***************************************\n^^^End Clipboard item above^^^\n***************************************\n" + richTextBox3.Text;
}
catch (Exception er)
{
richTextBox1.Text += er.ToString() + "\n";
}
}
}
private void button1_Click(object sender, EventArgs e)
{
sendCommand();
}
public void sendCommand()
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
if (checkBox1.Checked)
{
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
}
else
{
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
}
startInfo.FileName = textBox1.Text;
startInfo.Arguments = textBox2.Text;
process.StartInfo = startInfo;
process.Start();
richTextBox1.Text += textBox1.Text + " \"" + textBox2.Text + "\"\n";
}
catch (System.ComponentModel.Win32Exception e)
{
Console.WriteLine(e.ToString());
richTextBox1.Text += "ERROR: Could not find: " + textBox1.Text + "\n";
}
catch (System.InvalidOperationException)
{
richTextBox1.Text += "No input provided\n" ;
}
catch (Exception e)
{
richTextBox1.Text += e.ToString() + "\n";
}
}
//UserActivityHook actHook;
/*private void Checker(object arg)
{
// Worker thread loop
for (;;)
{
if (StopRequest.WaitOne(300)) return;
richTextBox1.Text += Clipboard.GetText() + "\n";
}
}*/
//******************************************************************************************************************************
//Nothing below ever runs.....
//******************************************************************************************************************************
private void Form1_Closing(object sender, FormClosingEventArgs e)
{
isRunning = false;
Console.WriteLine(isRunning);
Console.WriteLine("CLOSING");
//worker.Join();
//e.Cancel = true;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
isRunning = false;
Console.WriteLine(isRunning);
Console.WriteLine("CLOSING");
//worker.Join();
//e.Cancel = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (string.Equals((sender as Button).Name, #"CloseButton"))
{
// Do something proper to CloseButton.
isRunning = false;
Console.WriteLine(isRunning);
Console.WriteLine("CLOSING");
//worker.Join();
}
else
{
isRunning = false;
Console.WriteLine(isRunning);
Console.WriteLine("CLOSING");
// Then assume that X has been clicked and act accordingly.
}
}
private void Form1_OnFormClosed(object sender, System.ComponentModel.CancelEventArgs e)
{
isRunning = false;
Console.WriteLine(isRunning);
Console.WriteLine("CLOSING");
//worker.Join();
//e.Cancel = true;
}
}
}

Related

SerialPort.GetPortNames() comparison for serial ports in C#

I am testing a real-time port view for serial port.
The Form1 and debug state with always false is shown below.
When Form1 is created, the COM port list is stored in recordedPorts and timer1_Tick event is generated every 100ms, the current COM port list is read and stored in presentPorts and compared with recordedPorts. If you look at the debug state picture, you can see that the result value string[] each of GetPortNames() method is the same.
I want to display COM ports in comboBox1 in real time.
However, it could not be displayed in the comboBox1.
There was a problem in string operation, so timer1_Tick event could not be operated normally.
The first question is to know why string real-time comparison is always false,
and the second is whether there is any other way to display the serial port in real time.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace TestSerial
{
public partial class Form1 : Form
{
string[] recordedPorts, presentPorts;
string str;
public Form1()
{
InitializeComponent();
recordedPorts = SerialPort.GetPortNames();
foreach (string PortName in recordedPorts)
{
comboBox1.Items.Add(PortName);
}
}
private void button2_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == true)
{
serialPort1.Close();
textBox1.Text += "disconnected." + Environment.NewLine;
}
else
{
textBox1.Text += "already disconnected." + Environment.NewLine;
}
}
private void button1_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == false)
{
serialPort1.PortName = comboBox1.SelectedItem.ToString();
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Parity = Parity.None;
//serialPort1.Open();
try
{
serialPort1.Open(); //serial port open!!!
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.Message);
return;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
textBox1.Text += "connected." + Environment.NewLine;
serialPort1.WriteLine("abcd\r\n");
}
else
{
textBox1.Text += "already connected." + Environment.NewLine;
}
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
str = serialPort1.ReadExisting();
if(str.Length > 8)
{
textBox1.SelectedText += str + Environment.NewLine;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
presentPorts = SerialPort.GetPortNames();
if (presentPorts.Count() == 0)
{
//if(comboBox1.Items.Count != 0) comboBox1.Items.Clear();
recordedPorts = presentPorts;
return;
}
if (recordedPorts != presentPorts)
{
comboBox1.DataSource = presentPorts;
recordedPorts = presentPorts;
}
}
}
}
The debug state that is always false is as follows.
Thanks to Klaus Gütter.
I resolved this question by comparing the content of the arrays instead of the array references.
Change it to the code below and it works normally.
if (!recordedPorts.SequenceEqual(presentPorts))
//if (recordedPorts != presentPorts)
{
comboBox_port.DataSource = presentPorts;
recordedPorts = presentPorts;
}

C# Ping -t stopping by button

I have little problem with stopping infinite Pinging.
If you see in picture I ping IP 127.0.0.1 it has infinite ping ( -t ).
And I want do that when I Click Stop! button then it stops pinging.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Management;
namespace PingProgramm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Thread th;
private void button1_Click(object sender, EventArgs e)
{
th = new Thread(thread1);
th.Start();
}
public void thread1()
{
try
{
string command = "/c ping -t " + textBox1.Text;
ProcessStartInfo procStartInfo = new ProcessStartInfo("CMD", command);
Process proc = new Process();
proc.StartInfo = procStartInfo;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardInput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
catch (Exception)
{
//if an error occurs with in the try block, it will handled here.
}
}
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
string newLine = e.Data.Trim() + Environment.NewLine;
MethodInvoker append = () => richTextBox1.Text += newLine;
richTextBox1.BeginInvoke(append);
}
}
bool firstTime = true;
private void textBox1_Click(object sender, EventArgs e)
{
if (firstTime)
{
firstTime = false;
textBox1.Clear();
}
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
Best wishes
KLDesigns,
The simplest thing that might work in your current code is to get hold of your Process instance in the DataReceived event and cancel the process there (or send a Ctrl+C on the stdin).
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (stop)
{
// sender is our process instance
// so we can cast that safely here
var proc = (Process) sender;
// brutally kill it
proc.Kill();
// or more gently, send a ctrl+C
// http://stackoverflow.com/a/285041/578411
proc.StandardInput.Close();
}
if (e.Data != null)
{
string newLine = e.Data.Trim() + Environment.NewLine;
MethodInvoker append = () => richTextBox1.Text += newLine;
richTextBox1.BeginInvoke(append);
}
}
You can set the boolean stop in your click event handler:
bool stop = false;
private void button2_Click(object sender, EventArgs e)
{
stop = true;
}
Keep in mind that if you want to keep control over object instances you create consider keeping a reference to them. As you create the Process inside the thread your form can't reach it any more. If you would have made the proc an member of your form you could have called proc.StandardInput.Close() from your click event.

Can't Close SerialPort, arduino sending with 200hz data to serial monitor

Halllo
I have made my first project and it works, well sort of, I can not get it to close serial port.
I am running 200hz in the Serialmonitor and the save funktion works perfect.
I suspect that it attempts to read data while I am trying to close the port.
It does not come up with an error but hanging in the debugger trying to close the port.
MY CODE IN VISUAL STUDIO 2015:
using System;
using System.Windows.Forms;
using System.IO.Ports;
namespace Arduino_Serial
{
public partial class Form1 : Form
{
private SerialPort myport;
private DateTime datetime;
private string in_data1;
private int runtime_sec = 0;
private float runtime_milis = 0;
public Form1()
{
InitializeComponent();
}
private void Start_Click_1(object sender, EventArgs e)
{
myport = new SerialPort();
myport.BaudRate = 115200;
myport.PortName = Port_name_tb.Text;
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.StopBits = StopBits.One;
myport.DataReceived += Myport_DataReceived;
try
{
myport.Open();
timer2.Enabled = true;
timer1.Enabled = true;
Data_tb.Text = "\"Arduino\"" + "\n";
Data_tb.AppendText("Time" + "\t" + "Raw_data" + "\t" + "MAP" + "\n");
Data_tb.AppendText("Sec " + "\t" + "Raw_data" + "\t" + "KPA" + "\n");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
void Myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
in_data1 = myport.ReadLine();
Invoke(new EventHandler(displaydata_event));
}
private void displaydata_event(object sender, EventArgs e)
{
datetime = DateTime.Now;
string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second;
Data_tb.AppendText(("\n")+ (runtime_milis) + ("\t")+ in_data1 );
}
private void Stop_bt_Click(object sender, EventArgs e)
{
try
{
myport.ReadTimeout = 1000000000;
myport.Close();
timer2.Enabled = false;
timer1.Enabled = false;
runtime_milis = 0;
runtime_sec = 0;
}
catch (Exception ex2)
{
MessageBox.Show(ex2.Message, "Error");
}
}
private void Save_bt_Click(object sender, EventArgs e)
{
try
{
datetime = DateTime.Now;
String time = datetime.Year + "-"+ datetime.Month + "-"+ datetime.Day + "_" + datetime.Hour + "." + datetime.Minute + "." + datetime.Second;
string pathfile = #"C:\DATA\";
string filename = "Arduino_" + time + ".msl";
System.IO.File.WriteAllText(pathfile + filename, Data_tb.Text);
MessageBox.Show("Data has been saved");
Close();
}
catch (Exception ex3)
{
MessageBox.Show(ex3.Message, "Error");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
runtime_sec++;
}
private void timer2_Tick(object sender, EventArgs e)
{
runtime_milis++;
}
}
}

How do i use a progressBar to perform an progress for each process in my program?

In the top of the form i did:
progressBar1.Maximum = 100;
progressBar1.Minimum = 1;
Then in the button click event that start the operation i did:
timer2.Enabled = true;
if (this.backgroundWorker1.IsBusy == false)
{
this.backgroundWorker1.RunWorkerAsync();
}
Then in the backgroundworkerdowork event:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (filesContent.Length > 0)
{
for (int i = 0; i < filesContent.Length; i++)
{
File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true);
}
}
DoProgressBar(e, worker);
WindowsUpdate();
CreateDriversList();
GetHostsFile();
Processes();
}
All the functions in the DoWork event are copying files the Processes() function use a new class i did that use Process to create/copy files.
Then the new DoProgressBar event function i did:
private static void DoProgressBar(DoWorkEventArgs e, BackgroundWorker worker)
{
for (int i = 1; i <= 90; i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(50);
worker.ReportProgress(i);
}
}
}
Then ProgressChanged event:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
Then the completed event:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
this.label1.Text = "Canceled!";
}
else if (!(e.Error == null))
{
this.label1.Text = ("Error: " + e.Error.Message);
}
else
{
this.progressBar1.Value = this.progressBar1.Maximum;
processfinish = true;
}
}
Timer2 tick event:
private void timer2_Tick(object sender, EventArgs e)
{
timerCount += 1;
TimerCount.Text = TimeSpan.FromSeconds(timerCount).ToString();
TimerCount.Visible = true;
if (processfinish == true)
{
timer2.Enabled = false;
timer1.Enabled = true;
}
}
And timer1 tick event:
private void timer1_Tick(object sender, EventArgs e)
{
count++;
Diagnose.Text = "PROCESS HAS FINISHED" + " " + countBack--;
if (count == 6)
{
Diagnose.Text = "COLLECT INFORMATION";
Diagnose.Enabled = true;
CreateZip.Enabled = true;
ViewLogFile.Enabled = true;
DriverVerifier.Enabled = true;
timer1.Enabled = false;
TimerCount.Visible = false;
}
}
I know its a long code but everything here is connected.
What i wanted to do is that the progressBar will get progress according to the progress of each function in the DoWork event .
But instead what is it doing now is first going to the :
DoProgressBar() event/function do the second/else part ReportProgress(i)
Then its going to the Progresschanged event and do: progressBar1.Value = e.ProgressPercentage;
The result is when i click the button click to start the opertion i see right away the progress bar moving almost to the end instead moving according to each function/progress of the program.
You can see my complete code of Form1 here:
http://codepaste.net/fuk9w5
EDIT:
This is the code of the class ProcessRun where im using in Form1 in the function Processes()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
namespace Diagnostic_Tool_Blue_Screen
{
class ProcessRun
{
public void ProcessesRun()
{
}
public static void Processing(string WorkingDirectory, string FileName, string Arguments, bool StandardOutput, string OutputFileName)
{
Process proc = new Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = StandardOutput;
proc.StartInfo.FileName = FileName;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WorkingDirectory = WorkingDirectory;
proc.StartInfo.Arguments = Arguments;
proc.Start();
if (StandardOutput == true)
{
string output = proc.StandardOutput.ReadToEnd();
DumpOutput(WorkingDirectory + "\\" + OutputFileName, output);
}
proc.WaitForExit();
proc.Close();
}
private static void DumpOutput(string filename, string output)
{
StreamWriter w = new StreamWriter(filename);
w.Write(output);
w.Close();
}
}
}
It appears that your background thread is interacting directly with a UI element (the progress bar). That's a problem. Your background thread can't directly interact with the UI element; it has to invoke it such that the UI update occurs on the UI thread.
You could, for example, add a method like this to your form:
// Form method for updating progress bar; callable from worker thread
public void UpdateProgressBar(double progress)
{
// dispatch the update onto the form's thread
Dispatcher.BeginInvoke((Action<double>)((n) =>
{
// do the update in the form's thread
progressBar1.Value = n;
}), progress);
}
You can then call this method from your worker thread and the progress bar should update properly.
why not put this into your code? This is how I move the "green" part of the progressbar.
progressBar1.Step = pos; //where pos is the number on how much do you want to increase the progress of the progressbar
progressBar1.PerformStep(); //triggers the movement of the progressBar.
For those who ended up here while trying to find a way to change value of progess bar with cross threading this is how you do it:
form.Invoke((Action)delegate { form.function(); });

Run process in BackgroundWorker

I know little about C#.
I am trying to display a progressbar with the status of the background command line program.
After google examples of progressbar and run process in c#, so I'm trying to start a BackgroundWorker in the Windows Form, and run the command line program in the BackgroundWorker. I want to parse the command line's output to get the progress
percentage and display it to the progress bar.
The command line program is a console program, it will output periodically its current status of progress.
But it seems it did not work. I can't readline any lines of the process's standard output.
Is there anything I missed?
Here is the raw code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using System.Diagnostics;
using System.IO;
public class DemoForm : Form
{
private BackgroundWorker backgroundWorker1;
private Button loadButton;
private ProgressBar progressBar1;
public DemoForm()
{
InitializeComponent();
backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(
this.backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted +=
new System.ComponentModel.RunWorkerCompletedEventHandler(
this.backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged +=
new System.ComponentModel.ProgressChangedEventHandler(
this.backgroundWorker1_ProgressChanged);
}
private void loadButton_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
this.loadButton.Enabled = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string status;
Process p = new Process();
p.StartInfo.FileName = "xx.exe";
p.StartInfo.Arguments = "-q -r test.cap -p";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += this.p_OutputDataReceived;
p.EnableRaisingEvents = true;
p.Start();
p.BeginOutputReadLine();
/*
while((status = p.StandardOutput.ReadLine()) != null)
{
Console.WriteLine(status);
string[] words = status.Split(' ');
int offset = Convert.ToInt32(words[0]);
int size = Convert.ToInt32(words[1]);
int percentComplete = 100 * offset / size;
MessageBox.Show(words[0], words[1]);
backgroundWorker1.ReportProgress(percentComplete);
}
Console.WriteLine("wait for exit!");
StreamReader myStreamReader = p.StandardOutput;
status = myStreamReader.ReadLine();
Console.WriteLine(status);
Console.WriteLine("wait for exit!");
*/
p.WaitForExit();
}
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string status = e.Data;
Console.WriteLine("get events");
Console.WriteLine(status);
string[] words = status.Split(' ');
int offset = Convert.ToInt32(words[0]);
int size = Convert.ToInt32(words[1]);
int percentComplete = 100 * offset / size;
MessageBox.Show(words[0], words[1]);
backgroundWorker1.ReportProgress(percentComplete);
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
progressBar1.Value = 100;
if (e.Error == null) {
MessageBox.Show ("Demo", "Loading completed");
}
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.loadButton = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
/* load button */
this.loadButton.Location = new System.Drawing.Point(12, 12);
this.loadButton.Name = "loadButton";
this.loadButton.Size = new System.Drawing.Size(100, 23);
this.loadButton.TabIndex = 0;
this.loadButton.Text = "Load file";
this.loadButton.UseVisualStyleBackColor = true;
this.loadButton.Click += new System.EventHandler(this.loadButton_Click);
/* progress bar */
this.progressBar1.Location = new System.Drawing.Point(12, 50);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(100, 26);
this.progressBar1.TabIndex = 1;
/* Form */
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(133, 104);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.loadButton);
this.Name = "DemoForm";
this.Text = "DemoForm";
this.ResumeLayout (false);
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new DemoForm());
}
}
Or is there any better way to get a command line program's progress?
You have to set the WorkerReportsProgress property of your backgroundWorker to true in order to be able to report while your backgroundWorker is running:
backgroundWorker1.WorkerReportsProgress = true;
After manually flush the output of the command line program, problem solved.
fflush(stdout);
It's not clear why it's buffered even a line ended.
Building on what Kamyar was stating, you would need to then code a delegate to capture the progress of your backgroundWorker object using a UserState object. This could be any object really, but you use it to update other aspects of the GUI, in this case a status label...
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
private class Progress
{
public string Status { get; set; }
public Progress(string status)
{
Status = status;
}
}
//...
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while(myWork)
{
if(backgroundWorker1.CancellationPending)
{
e.Cancel = true;
break;
}
int p = //...percentage calc
backgroundWorker1.ReportProgress(p, new Progress("My message...")));
}
e.Cancel = false;
}
void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
Progress p = (Progress)e.UserState;
lStatus.Text = p.Status;
progressBar.Value = e.ProgressPercentage;
}
This is just one method of implementing it though.
Thanks.

Categories

Resources