Creating A Thread in C# - c#

Ok so I have the following code:
public partial class Form1 : Form
{
private void FileWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
ListViewItem newFile = new ListViewItem(new string[] { e.FullPath.ToString(), e.ChangeType.ToString() }, -1);
newFile.Tag = e.FullPath.ToString();
FileList.Items.Add(newFile);
}
private void CopyButton_Click(object sender, EventArgs e)
{
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged +=
new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int TotalFiles = FileList.CheckedItems.Count;;
int CurrentFile = 1;
foreach (ListViewItem CheckedFile in FileList.CheckedItems)
{
backgroundWorker1.ReportProgress((CurrentFile / TotalFiles) * 100);
string FileBuilder = Settings.Default.Destination + Path.GetFileName(CheckedFile.Tag.ToString());
if (File.Exists(FileBuilder) == false)
{
File.Copy(CheckedFile.Tag.ToString(), FileBuilder);
}
CurrentFile++;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
CopyProgressBar.Value = e.ProgressPercentage;
}
}
It keeps telling me that the report progress method in the DoWork event doesn't exist in the current context, anyone know why? Please forgive me if this is a noob error, im new.

backgroundWorker1 is a local variable.
It doesn't exist outside of CopyButton_Click.
You can either put it in a class field, or cast it from the sender parameter.

private void CopyButton_Click(object sender, EventArgs e)
{
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
}
you BackgroundWorker is init on start method and dispose when finish
try to declare BackgroundWorker in class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using FileWatchDog.Properties;
using System.Text.RegularExpressions;
namespace FileWatchDog
{
public partial class Form1 : Form
{
BackgroundWorker backgroundWorker1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void FileWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
ListViewItem newFile = new ListViewItem(new string[] { e.FullPath.ToString(), e.ChangeType.ToString() }, -1);
newFile.Tag = e.FullPath.ToString();
FileList.Items.Add(newFile);
}
private void CopyButton_Click(object sender, EventArgs e)
{
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int TotalFiles = FileList.CheckedItems.Count;;
int CurrentFile = 1;
foreach (ListViewItem CheckedFile in FileList.CheckedItems)
{
backgroundWorker1.ReportProgress((CurrentFile / TotalFiles) * 100);
string FileBuilder = Settings.Default.Destination + Path.GetFileName(CheckedFile.Tag.ToString());
if (File.Exists(FileBuilder) == false)
{
File.Copy(CheckedFile.Tag.ToString(), FileBuilder);
}
CurrentFile++;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
CopyProgressBar.Value = e.ProgressPercentage;
}
}
}

Related

How can I execute multiple commands waiting for each command to finish before starting the next one?

I have three commands to execute waiting for each command to finish before starting the next one.
Based on my implementation after completing the first one the second one will start but backgroundWorker1_RunWorkerCompleted won't raise at all.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace cmd_commands
{
public partial class Form1 : Form
{
string[] commands = new string[] {
#"test",
#"test1",
#"test2" };
int command = 0;
public Form1()
{
InitializeComponent();
}
public void runCmd(string command)
{
ProcessStartInfo cmdsi = new ProcessStartInfo("cmd.exe");
cmdsi.Arguments = command;
Process cmd = Process.Start(cmdsi);
cmd.WaitForExit();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
runCmd(commands[command]);
backgroundWorker1.ReportProgress(0, command);
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text = "Working on command number: " + e.UserState.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
command++;
runCmd(commands[command]);
}
}
}
BackgroundWorker is one time usage only i.e once the state is Completed it wont restart, u need to re-instantiate it.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
command++;
if (command < commands.Length)
{
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork += this.backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged += this.backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerCompleted += this.backgroundWorker1_RunWorkerCompleted;
backgroundWorker1.RunWorkerAsync();
}
}

Backgroundworker lag when starting, split method for multiple threads

The below code is for searching files. The thing is that when I select a large folder (like C disk) program starts with some delay. I think I need to divide disk into smaller parts (folders) and run it on different threads, but I do not know how.
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.Tasks;
using System.Threading;
using System.IO;
using System.Collections;
using System.Diagnostics;
namespace failu_paieska
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
FolderBrowserDialog Folder = new FolderBrowserDialog();
Stopwatch stopwatch = new Stopwatch();
static List<string> lstFilesFound = new List<string>();
int fileCount;
int fileCount1;
//string test;
private void Form1_Load(object sender, EventArgs e)
{
//label2.Text = Environment.ProcessorCount.ToString();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = Folder.ShowDialog();
textBox2.Text = Folder.SelectedPath.ToString();
}
private void IdetiIListbox()
{
foreach (string n in lstFilesFound.ToList())
{
stopwatch.Start();
if (Path.GetFileName(n).Contains(textBox1.Text.ToString()))
{
this.BeginInvoke(new MethodInvoker(() =>
{
listBox1.Items.Add(n);
//progressBar1.Value++;
}));
}
}
stopwatch.Stop();
int paieska = listBox1.Items.Count;
this.BeginInvoke(new MethodInvoker(() =>
{
textBox3.Text = Convert.ToString(stopwatch.Elapsed);
}));
}
public void Ieskoti1()
{
foreach (string ff in Directory.EnumerateFiles(textBox2.Text.ToString(), "*.*"))
{// Paima failus is pirmo katalogo
lstFilesFound.Add(ff);
fileCount1 = lstFilesFound.Count();
}
}
private void button2_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync(textBox2.Text.ToString());
}
}
static void DirSearch(string sDir)
{
foreach (string d in Directory.EnumerateDirectories(sDir))
{
try
{
lstFilesFound.Add(d);
//visoFailu += 1;
foreach (string f in Directory.EnumerateFiles(d, "*.*"))
{
//visoFailu += 1;
lstFilesFound.Add(f);
}
DirSearch(d);
}
catch (Exception ee)
{
}
continue;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label4.Text = (e.ProgressPercentage.ToString() + "%");
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
//DirSearch(textBox2.Text.ToString());
Ieskoti1();
DirSearch(textBox2.Text.ToString());
// IdetiIListbox();
for (int i = 0; i <= 100; i++)
{
backgroundWorker1.ReportProgress(i);
System.Threading.Thread.Sleep(100);
}
}
private void backgroundWorker1_RunWorkerCompleted_1(object sender, RunWorkerCompletedEventArgs e)
{
//DirSearch(textBox2.Text.ToString());
IdetiIListbox();
if (e.Cancelled == true)
{
MessageBox.Show("Cancelled!");
}
else if (e.Error != null)
{
MessageBox.Show("Error: " + e.Error.Message);
}
else
{
MessageBox.Show("Done!");
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
fileCount = Directory.GetFiles(textBox2.Text.ToString()).Length;
}
}
}

What's the best way to perform recurring actions with different buttons in c#

This is my current code:
subject subject1;
string DocPath = AppDomain.CurrentDomain.BaseDirectory + "Documents/";
public Form1()
{
InitializeComponent();
subject1 = new subject();
}
public class subject
{
Form1 frm;
public void changeTab(int tabPage/* , Form1 frm1 */, Form1 frm1)
{
frm = frm1;
frm.TabControlSubjects.SelectTab(tabPage);
}
}
private void materialRaisedButton1_Click(object sender, EventArgs e)
{
subject1.changeTab(0, this);
}
private void materialRaisedButton2_Click(object sender, EventArgs e)
{
subject1.changeTab(1, this);
}
private void materialRaisedButton4_Click(object sender, EventArgs e)
{
subject1.changeTab(2, this);
}
private void materialRaisedButton3_Click(object sender, EventArgs e)
{
subject1.changeTab(3, this);
}
private void materialRaisedButton8_Click(object sender, EventArgs e)
{
subject1.changeTab(4, this);
}
private void materialRaisedButton7_Click(object sender, EventArgs e)
{
subject1.changeTab(5, this);
}
private void materialRaisedButton6_Click(object sender, EventArgs e)
{
subject1.changeTab(6, this);
}
private void materialRaisedButton5_Click(object sender, EventArgs e)
{
subject1.changeTab(7, this);
}
private void materialRaisedButton12_Click(object sender, EventArgs e)
{
subject1.changeTab(8, this);
}
private void materialRaisedButton11_Click(object sender, EventArgs e)
{
subject1.changeTab(9, this);
}
private void materialRaisedButton10_Click(object sender, EventArgs e)
{
subject1.changeTab(10, this);
}
private void materialRaisedButton9_Click(object sender, EventArgs e)
{
subject1.changeTab(11, this);
}
Is there a more efficient way to do this? Because if i look at it now it seems like there could be a better way to do this. I'm very new at C# and I'm still learning as I speak. Any advice/tips is welcome.
thank you for reading.
Try this. I extracting the number of the button from the text name of the button.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
subject subject1;
string DocPath = AppDomain.CurrentDomain.BaseDirectory + "Documents/";
public Form1()
{
InitializeComponent();
subject1 = new subject();
materialRaisedButton1.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton2.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton3.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton4.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton5.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton6.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton7.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton8.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton9.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton10.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton11.Click += new EventHandler(materialRaisedButton_Click);
materialRaisedButton12.Click += new EventHandler(materialRaisedButton_Click);
}
public class subject
{
Form1 frm;
public void changeTab(int tabPage/* , Form1 frm1 */, Form1 frm1)
{
frm = frm1;
frm.TabControlSubjects.SelectTab(tabPage);
}
}
const string buttonPrefix = "materialRaisedButton";
private void materialRaisedButton_Click(object sender, EventArgs e)
{
Button button = sender as Button;
string name = button.Text;
int number = int.Parse(name.Substring(buttonPrefix.Length));
subject1.changeTab(number, this);
}
}
}​

"System.UnauthorizedAccessException" error when opening second serial port

i Need to open a second serialPort in my Visual C# program to read data from my arduino.
it already worked fine, but in the case you see below it does not work..
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;
using CommandsPD4I;
namespace CSharpExample
{
public partial class CSharpExample : Form
{
public ComMotorCommands motor1;
public CSharpExample()
{
InitializeComponent();
motor1 = new ComMotorCommands();
motor1.SetSteps(Convert.ToInt32(numericSchritte.Value));
}
SerialPort arduino;
delegate void InvokeLB(string Data);
InvokeLB lbRecievedDelegate;
int xPos = 0;
private void StartBtn_Click(object sender, EventArgs e)
{
// Set comm settings for motor 1
motor1.SelectedPort = ComPortBox1.Text;
motor1.Baudrate = Convert.ToInt32(BaudrateBox1.Text);
// Set motor address
motor1.MotorAddresse = Convert.ToInt32(Motor1ID.Value);
// Set relative positioning mode
motor1.SetPositionType(1);
// Start travel profile
if (motor1.ErrorFlag)
{
StatusLabel1.Text = "Status 1: " + motor1.ErrorMessageString;
}
else
{
StatusLabel1.Text = "Status 1: OK";
}
}
private void StopBtn_Click(object sender, EventArgs e)
{
// Stop travel profile
motor1.StopTravelProfile();
}
private void timer1_Tick(object sender, EventArgs e)
{
lblPosition.Text = Convert.ToString(motor1.GetPosition());
lblStatus.Text = motor1.ErrorMessageString;
// this.chart1.Series["Kraft"].Points.AddXY(xPos, Convert.ToDouble(lblKraft.Text));
// xPos++;**strong text**
}
private void btnHoch_Click(object sender, EventArgs e)
{
motor1.SetDirection(0);
motor1.SetPositionType(1);
motor1.StartTravelProfile();
}
private void btnRunter_Click(object sender, EventArgs e)
{
motor1.SetDirection(1);
motor1.SetPositionType(1);
motor1.StartTravelProfile();
}
private void numericSchritte_ValueChanged(object sender, EventArgs e)
{
motor1.SetSteps(Convert.ToInt32(numericSchritte.Value));
}
private void numericGeschwindigkeit_ValueChanged(object sender, EventArgs e)
{
motor1.SetMaxFrequency(Convert.ToInt32(numericGeschwindigkeit.Value));
}
private void btnDiagramm_Click(object sender, EventArgs e)
{
if (timer1.Enabled)
{
timer1.Stop();
}
else
{
timer1.Start();
}
}
private void btnResetDiagramm_Click(object sender, EventArgs e)
{
this.chart1.Series["Kraft"].Points.Clear();
xPos = 0;
}
private void arduino_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string RecievedLine = " ";
while (RecievedLine != "")
{
RecievedLine = arduino.ReadLine();
lblKraft.Invoke(lbRecievedDelegate, new object[] { RecievedLine });
}
}
void Invokelabel1(string Data)
{
label1.Text = Data;
this.chart1.Series["Kraft"].Points.AddXY(xPos, Convert.ToDouble(lblKraft.Text));
xPos++;
}
private void btnArduino_Click(object sender, EventArgs e)
{
//Hier erstellen wir unseren Serialport und legen die Einstellungen fest
arduino = new SerialPort("COM7", 9600);
if (!arduino.IsOpen)
{
arduino.Open();
if (arduino.IsOpen)
{
lblArduino.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(200)))), ((int)(((byte)(0)))));
lblArduino.Text = "Verbunden mit " + arduino.PortName;
}
}
lbRecievedDelegate = new InvokeLB(Invokelabel1);
arduino.DataReceived += new SerialDataReceivedEventHandler(arduino_DataReceived); //DataRecieved Event abonnieren
}
}
}
When i leave out this:
motor1.SelectedPort = ComPortBox1.Text;
motor1.Baudrate = Convert.ToInt32(BaudrateBox1.Text);
then it works..
I hope you can help :)

Working with Grid using BackgroundWorker

I have a GridControl which I populate using a BackgroundWorker. Then I'm using another BackgroundWorker to perform some calculations on the dataset which is the datasource of the GridControl. As I'm trying to do this a cross thread operation on the GridControl error is thrown. I'm unable to understand that despite not performaing any operation on the gridcontrol itself how the error is generating. (I'm using DevExpress, but that should not change the concept).
Also is there any way I can use one BackgroundWorker to do different work, i.e. make this code more efficient.
Here is my code:-
public partial class MainForm : XtraForm
{
private BackgroundWorker loadworker = new BackgroundWorker();
private BackgroundWorker calcworker = new BackgroundWorker();
private AutoResetEvent resetEvent = new AutoResetEvent(false);
private Database _db = EnterpriseLibraryContainer.Current.GetInstance<Database>("ConnString");
private DataSet ds;
public MainForm()
{
InitializeComponent();
loadworker.DoWork += loadworker_DoWork;
loadworker.RunWorkerCompleted += loadworker_RunWorkerCompleted;
loadworker.ProgressChanged += loadworker_ProgressChanged;
loadworker.WorkerReportsProgress = true;
calcworker.DoWork += calcworker_DoWork;
calcworker.RunWorkerCompleted += calcworker_RunWorkerCompleted;
calcworker.ProgressChanged += calcworker_ProgressChanged;
calcworker.WorkerReportsProgress = true;
}
private void calcworker_DoWork(object sender, DoWorkEventArgs e)
{
int _cnt = 0;
foreach (DataRow dr in ds.Tables[0].Rows)
{
dr["GROSS"] = (decimal)dr["BASIC"] + (decimal)dr["HRA"] + (decimal)dr["DA"];
_cnt += 1;
}
for (int i = 0; i <= _cnt; i++)
{
Thread.Sleep(100);
calcworker.ReportProgress((100 * i) / _cnt);
}
}
private void calcworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.SetState(true);
this.MainInit();
}
private void calcworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.pgb_DataProgress.Position = e.ProgressPercentage;
}
private void loadworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.pgb_DataProgress.Position = e.ProgressPercentage;
}
private void loadworker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
DbCommand _cmd = _db.GetSqlStringCommand("SELECT Z.EMP_CODE,Z.BASIC,Z.DA,Z.HRA,CAST(0 AS DECIMAL) GROSS FROM Z000000001 Z");
DataSet _data = _db.ExecuteDataSet(_cmd);
for (int i = 0; i <= 10; i++)
{
Thread.Sleep(500);
loadworker.ReportProgress((100 * i) / 10);
}
e.Result = _data;
}
catch (Exception ex)
{
e.Cancel = true;
}
}
private void loadworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.ds = (DataSet)e.Result;
this.gridControl1.DataSource = ds.Tables[0];
this.SetState(true);
this.MainInit();
}
private void btn_FetchData_Click(object sender, EventArgs e)
{
this.gridControl1.DataSource = null;
this.SetState(false);
loadworker.RunWorkerAsync();
}
private void SetState(bool _state)
{
this.btn_Calculate.Enabled = _state;
this.btn_ClearGrid.Enabled = _state;
this.btn_FetchData.Enabled = _state;
}
private void MainInit()
{
this.pgb_DataProgress.Position = 0;
}
private void btn_ClearGrid_Click(object sender, EventArgs e)
{
this.gridControl1.DataSource = null;
}
private void btn_Calculate_Click(object sender, EventArgs e)
{
if (this.gridControl1.DataSource == null)
{
DevExpress.XtraEditors.XtraMessageBox.Show("Data Not loaded", "Message");
return;
}
else
{
this.SetState(false);
calcworker.RunWorkerAsync();
}
}
}
After you attached the Table as DataSource it belongs to the GUI. Suppose your user alters/deletes a row while your Calc thread is running. All sorts of race conditions might happen.
In short, you cannot access controls on a thread other than UI thread on which they are created. So any control method/property call has to be marshall on the UI thread using Control.Invoke method.
For example, in your case loadworker_RunWorkerCompleted event handler will be invoked on a worker thread and accessing control property will throw an error. You need to modify event handler as
private void loadworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Action a = () => {
this.ds = (DataSet)e.Result;
this.gridControl1.DataSource = ds.Tables[0];
this.SetState(true);
this.MainInit();
};
this.gridControl1.Invoke(a);
}

Categories

Resources