Control/Sync variable between multiple threads c# - c#

I am having some timing issues with the following code. Basically I have "recordingOn", when True, it's suppose to start writing frames to file. In the below program, when I sometimes do Stop_Button_Click, I get an exception on "writer1.Write(frame1);" line, this is likely because it's doing so after I've already done dispose(). How do I synchronize this? thanks!
private bool recordingOn = false;
private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
if (!captureInProgress) //Start cameras streaming
{
camera1Capture.ImageGrabbed += ProcessFrame;
camera1Capture.Start();
}
else //Stop cameras streaming
{
camera1Capture.Stop();
imageBox1.Image = null;
camera1Capture.ImageGrabbed -= ProcessFrame;
}
captureInProgress = !captureInProgress;
}
private void ProcessFrame(object sender, EventArgs arg)
{
camera1Capture.Retrieve(frame1);
imageBox1.Image = frame1;
if (recordingOn)
{
try
{
writer1.Write(frame1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void Stop_Button_Click(object sender, EventArgs e)
{
// Doing other stuff...
recordingOn = false;
writer1.Dispose();
}

The basic issue is of shared variable across multiple threads. Please use lock to control access to shared variable. Lock ensures that at one time only one thread can access a variable.
private bool recordingOn = false;
private static object _lock = new Object();
private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
if (!captureInProgress) //Start cameras streaming
{
camera1Capture.ImageGrabbed += ProcessFrame;
camera1Capture.Start();
}
else //Stop cameras streaming
{
camera1Capture.Stop();
imageBox1.Image = null;
camera1Capture.ImageGrabbed -= ProcessFrame;
}
captureInProgress = !captureInProgress;
}
private void ProcessFrame(object sender, EventArgs arg)
{
camera1Capture.Retrieve(frame1);
imageBox1.Image = frame1;
lock (_lock)
{
if (recordingOn)
{
try
{
writer1.Write(frame1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
private void Stop_Button_Click(object sender, EventArgs e)
{
// Doing other stuff...
lock (_lock)
{
recordingOn = false;
writer1.Dispose();
}
}

Related

How to get media player file play finished finished event in xamarin.forms?

After file play finish I need to get event completed notification on how to implement in xamarin.forms
public void PlayAudioFile(String pathtowavfile)
{
try
{
var fileresouce = new Java.IO.File(pathtowavfile);
if (fileresouce.Exists())
{
player.Reset();
player.SetDataSource(pathtowavfile);
player.Prepare();
player.Completion += Player_Completion;
}
}
catch (Exception ex)
{
}
}
private void Player_Completion(object sender, EventArgs e)
{
throw new NotImplementedException();
}
public void Start()
{
player.SeekTo(length);
player.Start();
}
public void Pause()
{
if (player.IsPlaying)
{
player.Pause();
length = player.CurrentPosition;
}
}

DownloadProgressChanged get called only after file has been downloaded

Im trying to use the progress bar to track my download, the only problem the progress value changes only after the file is downloaded to the computer and not during its download.
Here is my code, any help will be appreciated.
public void DownloadZaq()
{
using (WebClient zaq = new WebClient())
{
zaq.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Zaq_DownloadProgressChanged);
zaq.DownloadFileCompleted += new AsyncCompletedEventHandler(Zaq_DownloadFileCompleted);
zaq.DownloadFileAsync(new Uri(http://example.com), #"c:\to\111.jpg");
}
}
public void Zaq_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("download completed");
}
public void Zaq_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
I think that DownloadFileAsync is blocking the main thread somehow while checking the DNS. This is what I would try
WebClient zaq;
public void DownloadZaq()
{
zaq = new WebClient();
zaq.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Zaq_DownloadProgressChanged);
zaq.DownloadFileCompleted += new AsyncCompletedEventHandler(Zaq_DownloadFileCompleted);
System.Threading.Tasks.Task.Run(() => // Workaround to allow Async call
{
try
{
zaq.DownloadFileAsync(new Uri(http://example.com), #"c:\to\111.jpg");
}
catch (Exception ex)
{
zag.Dispose();
}
});
}
public void Zaq_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("download completed");
zag.Dispose();
}
public void Zaq_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

Spambot repeat part won't spam fast

I'm working on a spambot but there is 1 problem I can't solve. I made buttons you can press, it says how much you want to spam. If you want to spam you will get a certain amount of time to go to the place where you want to spam. I made a function for how much the text will spam. But the problem is when it send 1 message it wait the certain amount of time time and not the 500 miliseconds
The script is written in C#. The target framework is: .NET Framework 4.6.1.
public partial class Form1 : Form
{
public void Time()
{
for (int i = 0; i <= 10;)
{
Stuur();
i++;
}
} // 10x
public void Stuur() // does the sending
{
System.Threading.Thread.Sleep(500);
SendKeys.Send(textBox3.Text);
SendKeys.Send("{ENTER}");
}
public Form1()
{
InitializeComponent();
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Rush B", "5 sec voor spam",
MessageBoxButtons.OK, MessageBoxIcon.Error);
System.Threading.Thread.Sleep(5000);
Time();
}
private void button2_Click(object sender, EventArgs e) // the credit
block
{
if (textBox6.Visible == true)
{
textBox6.Visible = false;
} else {
textBox6.Visible = true;
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
}
Maybe something along these lines?
public void Stuur() // does the sending
{
System.Threading.Thread.Sleep(5000);
SendKeys.Send(textBox3.Text);
SendKeys.Send("{ENTER}");
}
public Form1()
{
InitializeComponent();
}
private void textBox4_TextChanged(object sender, EventArgs e) { }
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= Int32.Parse(textBox.Text4); i++) {
Stuur();
}
}
private void button2_Click(object sender, EventArgs e) // the credit block
{
if (textBox6.Visible == true)
{
textBox6.Visible = false;
}
else
{
textBox6.Visible = true;
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e) { }
}
edit: closed parenthesis

Changing a single client server into a multiple server c#

Okay so I have ran into a problem, I have created a server which handles a single client and now I want to kick it up a notch and have it handle multiple clients at one time.
I have looked and tried to do this using HashTables and also Async but I keep getting stuck, this is a grey area for me as I have only just recently started dealing with sockets etc...
I wondered if anyone had a way of doing it?
Any advise will be taken on board.
This is my server code(If it helps).
namespace ChatServer
{
delegate void UpdateTextBox(string msg);
public partial class Form1 : Form
{
private TcpListener ConnectionListener;
private BinaryReader MessageReader;
private BinaryWriter MessageWriter;
private Socket ClientConnection;
private NetworkStream DataStream;
private Thread ListeningThread;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
IPAddress.Parse(textBox3.Text);//
ListeningThread = new Thread(new ThreadStart(ListenForConnections));
ListeningThread.Start();
}
catch (Exception)
{
MessageBox.Show("Wrong Ip Address");
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
if (ClientConnection.Connected)
{
MessageWriter.Write(textBox2.Text);
textBox2.Clear();
}
}
catch (Exception)
{
MessageBox.Show("no client is connected");
}
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
if (ClientConnection.Connected)
{
MessageWriter.Write(textBox2.Text);
textBox2.Clear();
}
}
catch (Exception)
{
MessageBox.Show("no client is connected");
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.Environment.Exit(System.Environment.ExitCode);
}
private void ListenForConnections()
{
try
{
ConnectionListener = new TcpListener(IPAddress.Parse(textBox3.Text), 80);
ConnectionListener.Start();
ChangeTextBoxContent("Listening For Connections");
ClientConnection = ConnectionListener.AcceptSocket();
DataStream = new NetworkStream(ClientConnection);
MessageReader = new BinaryReader(DataStream);
MessageWriter = new BinaryWriter(DataStream);
ChangeTextBoxContent("Connection Received");
HandleConnection();
MessageReader.Close();
MessageWriter.Close();
DataStream.Close();
ClientConnection.Close();
}
catch (Exception)
{
MessageBox.Show("Unable to connect, wrong ip address");
}
}
private void HandleConnection()
{
string message;
do
{
try
{
message = MessageReader.ReadString();
ChangeTextBoxContent(message);
}
catch (Exception)
{
ChangeTextBoxContent("connection Lost");
break;
}
} while (true);
}
private void ChangeTextBoxContent(string tx)
{
if (textBox1.InvokeRequired)
{
Invoke(new UpdateTextBox(ChangeTextBoxContent), new object[] { tx });
}
else
{
textBox1.Text += tx + "\r\n";
}
}
}
}
Thank you in advance.
You should handle each of your connections in a separate thread. Create a loop that constantly listens for remote connections, and when a remote connection is called, create a new thread with the connection as the object parameter.

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