I have developed a socket program . I have the problem with the client side socket program it gets data from multiple servers,one at a time and update the details in listview. It happens inside a infinite loop.
while(true)
{
}
I want to exit this this loop in the middle period, I used button click event to do that
foreach (Process myProc in Process.GetProcesses())
{
if (myProc.ProcessName == "procees name")
{
myProc.Kill();
}
}
but it's too slow, I want to pause that process and kill it. Help me to pause currently running process.
Since you mention the process is your own application, you can just exit the application yourself instead of killing the application. Your question turns out more to be "how can I exit my program".
Firstly, your button may not seem responsive since you're running an infinite loop. One (bad) way of doing it is like this:
private bool _exit = false; //member variable
while(true && !_exit)
{
Application.DoEvents();
}
Application.DoEvents is important to make your application keep listening to other actions. And then,
private void btn_Click(object sender, EventArgs e)
{
_exit = true;
}
The ideal way imo is to transfer the job of getting data from servers to a background process. May be something like this:
BackgroundWorker _backgroundWorker = new BackgroundWorker(); //member field
void Listen()
{
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.DoWork += (sender, e) => { while(condition)//bla bla; }
_backgroundWorker.RunWorkerAsync();
}
And then upon your cancellation click,
private void btn_Click(object sender, EventArgs e)
{
_backgroundWorker.CancelAsync();
}
There is no such feature to pause running process, so the answer is no.
If this would be possible you could change every process, and that is something which all software builders try to prevent.
You will need some way around.
However, if you have time you can try
http://www.c-sharpcorner.com/uploadfile/mmehta/multithreading311162005045743am/multithreading3.aspx
http://www.codeproject.com/Articles/2042/Using-events-for-thread-synchronization
If you want to handle multiple simultaneous socket connections, I'd suggest using SocketAsyncEventArgs instead of traditional while (true).
Take a look at this article:
C# SocketAsyncEventArgs High Performance Socket Code
And the simplest (but not flawless) solution that usually comes with the while loop is something like this:
private volatile bool _running = true;
...
while (_running)
{
// Do stuff
}
...
public void ButtonClick(object sender, EventArgs e)
{
_running = false;
}
Depending on your application (how many threads, what ui library), you could just use
Application.Exit. Perhaps you should set the IsBackground property of your worker threads when creating them.
Just imagine what would happen, if it were possible to pause the process. The user clicks the button, your program pauses the current process, and than there is nothing to do, because you just paused yourself. The code to kill the process would never run.
You could suspend all the threads of a remote process.
http://www.codeproject.com/Articles/2964/Win32-process-suspend-resume-tool
Related
I am writing an application where I have a Process running in a BackgroundWorker. I would like to support cancellation from the user interface, but I don't see an easy way to do this.
The Process is actually a fairly long running command line exe. The output is getting redirected asynchronously via the Progress.OutputDataReceived event and is being used to report progress to the GUI.
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
using (var process = new Process())
{
//...
process.Start()
//...
process.WaitForExit();
}
}
private void CancelWorker()
{
worker.CancelAsync();
// where to actually listen for the cancellation???
}
There doesn't appear to be a way to have the process "listen" for any input from the main thread aside from the StandardInput, but that won't work unless the app itself will response to a specific input to abort.
Is there a way to cancel a process based on a cancel request from the main thread?
For the purposes of my of the EXE running in the process, I can just call Process.Close() to exit without any side-effects, but the Process object is only known to the worker_DoWork() method, so I'll need to keep track of the Process instance for cancellation purposes... that's why I'm hoping there might be a better way.
(if it matters, I am targeting .NET 3.5 for compatibility issues.)
For cooperative cancellation, you need to listen to BackgroundWorker.CancellationPending
in BackgroundWorker.DoWork
event.
How to: Use a Background Worker
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
using (var process = new Process())
{
//...
process.Start()
//...
while(true)
{
if ((sender as BackgroundWorker).CancellationPending && !process.HasExited)
{
process.Kill();
break;
}
Thread.Sleep(100);
}
process.WaitForExit();
}
}
try this, this might be help you, in easy way
private System.Threading.TimerCallback worker;
private System.Threading.Timer workertimer ;
private void worker_DoWork()
{
//You codes
}
private void StartWorker()
{
worker = new System.Threading.TimerCallback(worker_DoWork);
workertimer = new System.Threading.Timer(worker, null, 1000, 1000);
}
private void CancelWorker()
{
worker.Dispose();
}
When a user clicks on Run, the application runs through a lot of code to generate a model and display it in a Chart. The Run takes about 1-2 minutes to run. I also have a Cancel button that gets enabled after the Run button is clicked. I am working with DotSpatial, so my buttons are on a plugin panel in a ribbon UI. The click event on the Run and Cancel start in the plugin, which calls the back-end class's code Run and Click.
When the user hits cancel after the run starts, there is a delay, but the cancel method is invokes and executes, but the run never stops and we eventually see the chart display. So, I'm thinking I need a separate thread for the Run. I'm fairly new to programming, and never worked with Threading. I've looked into it and added the below code, but my thread method isn't running. Here's my code:
The Run button is clicked:
This is at the top:
//check to see if RunModel thread needs to stop or continue
private volatile bool stopRun = false;
private Thread runThread;
Then this is the method that's called from the click event:
public void btnRun_testingThread(object sender, EventArgs e)
{
//create a new thread to run the RunModel
if (runThread == null)
{
//we don't want to stop this thread
stopRun = false;
runThread = new Thread(RunModel);
runThread.Start(); <--this isn't doing anything
}
So, I would think that when the code gets to the runThread.Start(), it would jump into my RunModel method and start running through the code. But it doesn't. Additionally, I'll want to cancel out of this thread (once I have it working correctly), so I have this, which gets called from the cancel click method:
private void StopRunThread()
{
if (runThread != null)
{
//we want to stop the thread
stopRun = true;
//gracefully pause until the thread exits
runThread.Join();
runThread = null;
}
}
Then the this is the RunModel() where I'm checking occasionally to see if the stopRun bool has changed.
public void RunModel()
{
...some code.....
//check to see if cancel was clicked
if (stopRun)
{
....clean up code....
return;
}
....some more code....
//check to see if cancel was clicked
if (stopRun)
{
....clean up code....
return;
}
}
And the cancel button click method:
public void btnCancel_Click(Object sender, EventArgs e)
{
stopRun = true;
StopRunThread();
//the model run has been canceled
....some code.....
}
Any help on getting the thread.start to actually run the Run method? Then do I need to constantly check the volatile bool in the run in order to clean everything up if it's being stopped? Thanks!
I think you'd be best looking at the BackgroundWorker - this essentially runs separately but can watch out for cancellation commands. Make sure you add 'WorkerSupportCancellation' when you initialise it:
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); // This does the job ...
backgroundWorker1.WorkerSupportsCancellation = true; // This allows cancellation.
Then on click you can start your process:
public void btnRun_testingThread(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
Your cancel button can issue a cancellation request:
public void btnCancel_Click(Object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
Then your worker can monitor for this as it's doing it's work ...
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
if (backgroundWorker1.CancellationPending)
{
break;
}
else
{
// Do whatever you're doing.
}
}
e.Result = backgroundWorker1.CancellationPending ? null : orders;
}
You can enhance this further by adding progress bars etc., but that gets a bit more complicated so I won't go into it here.
Considering new info provided in commend I believe you just missed a start of the RunModel() method in debugger because of wrong assumption regarding thread.Start() method behaviour.
Please see a note from MSDN, Thread.Start Method
Once a thread is in the ThreadState.Running state, the operating
system can schedule it for execution. The thread begins executing
at the first line of the method represented by the ThreadStart or
ParameterizedThreadStart delegate supplied to the thread constructor.
Small demonstration that thread start takes some time bits, for me it starts in 38-40 milliseconds:
Stopwatch watch = new Stopwatch();
Thread thread = new Thread((ThreadStart)watch.Stop);
thread.Start();
watch.Start();
Thread.Sleep(5000);
double startedAfter = watch.ElapsedMilliseconds;
Since .NET Framework 4.0 consider using TPL Tasks rather than threads explicitly, some pros:
You can easily synchronize with UI thread by passing in a Task UI Thread synchronization context
You can easily stop a Taks using CancellationToken
I have an application that imports data read from text files from a directory into a database. I have a UI that allows the user to click an import button and begin importing data and when the user clicks on that button again I wanted to stop importing the data in those files. I began using threads to allow this, so that I would not freeze up the UI while data was being imported. But Im having a few issues. I started using thread.Abort() to kill the thread after the user stops wanting to import but when the user clicks import again, some duplicate data is added to the database because it begins reading at the top of the text file which I dont want. I have been told to use ManualResetEvents and Thread.Join() to trigger for the import to finish, but im confused how that is supposed to work. Right now my code looks like this:
public ManualResetEvent event1 = new ManualResetEvent(false);
public Thread workerThread;
public Form1
{
InitializeComponent();
}
private void importButton_Click(object sender, EventArgs e)
{
if(importButton.Text == "Begin Import")
{
importButton.Text = "Stop Import";
//runs a service that begins reading and importing data and writing to
//a "console" box.
Service service = new Service(consoleBox);
//run the new thread to begin importing data
workerThread = new Thread(service.importData);
workerThread.Start();
}
else
{
importButton.Text = "Begin Import";
event1.Set();
while(!event1.WaitOne(TimeSpan.FromSeconds(4)))
{ //imports data for 30 more text files
service.importData(30);
workerThread.Join();
}
}
}
Basically what im trying to do is to keep the tread looping and checking to see if there is any files to be read, if there is then import The Data otherwise sleep for 4 seconds. Should I be using a threading Timer for this? I am a bit unsure of what to do.
Do not, in any way, block the UI thread by calling Thread.Join or ManualResetEvent.WaitOne. This will do exactly what you were trying to prevent; freeze the UI. Instead you need to create the MRE with its state initially set to true. Then in the importData method you need to periodically call WaitOne to see if importing should proceed (when the event is signaled) or pause (when the event is unsignaled).
Here is a rough sketch of how you would call WaitOne inside the importData method. Obviously, you would need to make adjustments to fit it into your specific implementation.
private void importData()
{
foreach (string filePath in GetFilesInSomeDirectory())
{
event1.WaitOne(); // Block when the MRE is unsignaled.
}
}
Then from your importButton.Click event handler you can call event1.Reset to pause the import operation or event1.Set to resume it.
Also, you should try to avoid calling Thread.Abort at all costs. It usually leads to more problems unless extra-special-nearly-impossible care is taken to avoid corrupting the state of the AppDomain.
Use timer for running the import process instead of thread, and define a variable to check if user request to stopinstead of thread.Abort() which by the way should be avoided.
In this code use System.Timers.Timer. and flag AutoReset property to false, so only import data if user not request to stop.
private System.Timers.Timer _importTimer = new System.Timers.Timer();
private volatile bool _requestStopImport = false;
public Form1()
{
InitializeComponent();
_importTimer.Interval = 4000;//4 seconds
_importTimer.AutoReset = false;//not automatically raise elapse event each time interval elapsed, only if we don't want to stop.
_importTimer.Elapsed += OnImportTimerElapced;
}
private void importButton_Click(object sender, EventArgs e)
{
if (importButton.Text == "Begin Import")
{
importButton.Text = "Stop Import";
StartImport();
}
else
{
importButton.Text = "Begin Import";
StopImport();
}
}
private void OnImportTimerElapced(object sender, System.Timers.TimerEventArgs e)
{
//runs a service that begins reading and importing data and writing to
//a "console" box.
Service service = new Service(consoleBox);//or maybe this would be a class level variable
service.importData();
if (!_requestStopImport)
{
_importTimer.Start();
}
}
private void StartImport()
{
_requestStopImport = false;
_importTimer.Start();
}
private void StopImport()
{
_requestStopImport = true;
_importTimer.Stop();
}
As you notice you don't have to use ManualResetEvent here. however if you want to be notified when code is completed or so you can use AutoResetEvent or raise an event for more detailed example check this.
Well, what I am trying to do is show a animated gif while it reads a directory full of files, however the UI freezes, which is ok, but i would like to keep the gif running till the operation is finished. Any ideas?
I am doing it on a Windows Form using VS2010 C#
Here is some example code how you can Load your files aysnchronous. Maybe it helps you. I like this way more than using DoEvents. With DoEvents I had already have some ungood side-effects, therefore I try not to use it.
BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};
bgWorker.DoWork += (s, e) => {
// Load here your file/s
// Use bgWorker.ReportProgress(); to report the current progress
};
bgWorker.ProgressChanged+=(s,e)=>{
// Here you will be informed about progress and here it is save to change/show progress. You can access from here savely a ProgressBars or another control.
};
bgWorker.RunWorkerCompleted += (s, e) => {
// Here you will be informed if the job is done.
// Use this event to unlock your gui
};
bgWorker.RunWorkerAsync();
You have two options.
Start a separate thread to handle the file operations.
periodically call Application.DoEvents() within the file loop. That will cause your app to process pending messages (thus updating your UI), but will negatively impact the speed of the file processing loop.
Posting from my phone so no example links.
Run enumeration is a separate thread and update the GUI in the main thread.
Would something like this work with backgroundWorker?
private void buttonRename_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
foreach (ListViewItem myitem in listView.Items)
{
try
{
//Rename
}
catch
{
}
}
}
I am trying to build a small application that logins into a server and gathers data from it constantly. The problem that I am having is that my GUI is slow to respond even when using either background worker or a thread. When my application tries to login into the server, I see "(Not Responding)" appear in my login form, but it logins in few seconds later without Windows giving the "The program has stopped responding... terminate application" dialog. When I click the start button on my application I noticed by GUI becomes very sluggish and unresponsive. I was wondering how I could improve the response time of my program. Here is the code for the Login form using a background worker and the code for my thread that gathers data from the server. I apologize for the last section of the code not being format correctly, but SO is being non-cooperative.
private void btnLogin_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtAccount.Text) || string.IsNullOrEmpty(txtPassword.Text))
{
MessageBox.Show("Must Enter Username and Password");
return;
}
btnLogin.Enabled = false;
account = txtAccount.Text;
password = txtPassword.Text;
accountType = cmbAccountType.SelectedItem.ToString();
loginBackgroundWorker.RunWorkerAsync();
}
private void loginBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
loginSuccess=tradingDesk.Login(account, password, accountType);
}
private void loginBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (loginSuccess)
{
this.DialogResult = DialogResult.OK;
}
btnLogin.Enabled = true;
}
private void btnStart_Click(object sender, EventArgs e)
{
Thread dataThread=new Thread(GetServerData);
dataThread.IsBackground=true;
try
{
dataThread.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}}
private void GetServerData()
{
try
{
while (true)
{
lock (myLock)
{
//Perform Server Task with large amounts of data
}
}
}
catch
{
//Handle exception code
}
}
Try using BackgroundWorker for your processing - easier than handling threads yourself unless you're in the business of handling threads in a pool and you like that stuff (or you've been doing it like that since v1.0 as I have - you're just used to it that way).
I also put all my UI interactions into a background thread and marshall the calls back through to the UI thread. This article should help you out on both: Tools for Updating Windows Forms UI from Background Threads
Another test is to swap out your call to tradingDesk.Login with a simple sleep to see if that changes anything. And how's your CPU? Happen to notice if the thread or process spikes in CPU usage? Even a multi-threaded app that eats up all your CPU will stutter - Flash comes to mind - slows down my entire system even other processes.
Try setting Thread.Priority to something lower than the GUI.
Also, your thread is on the same cpu/core as the app (same process) so if it uses 100% then even with a lowered priority you might notice a difference.
There is a library I can't recall off the top of my head for parallel processing across cpus/cores - try that if priority doesn't fix it
This seems strange to me...:
private void btnStart_Click(object sender, EventArgs e)
{
Thread dataThread = new Thread(GetServerData); // Won't this go out of scope?
dataThread.IsBackground = true;
try
{
dataThread.Start(); // Isn't this asynchronous (i.e. doesn't block)?
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Seems to me that either dataThread.Start() is a blocking call, thus causing your UI thread to stall, or it's a non-blocking call, in which case the local reference dataThread goes out of scope almost immediately (presumably before the thread has had time to finish it's work)?
This is a perfect example of why ThreadPool exists. Please note, when you pass the delegate to the method you want threaded to the ThreadPool, the main UI thread (the one that drives the message pump) is free and clear, waiting for the next UI event. Unless you are communicating frequently with the UI thread, there should be no reason that the UI thread is bogged down to the point of becoming unresponsive.
private void btnStart_Click(object sender, EventArgs e)
{
// spawn the GetServerData() method on the ThreadPool
ThreadPool.QueueUserWorkItem(new WaitCallback(GetServerData));
// after the above is called, you'll immediately get here because
// the UI thread is free from having to process GetServerData()
return;
}
Note: WaitCallback delegate requires a single parameter of an object. Also, note the comment on the "lock" statement below.
private void GetServerData(object o)
{
try
{
while (true)
{
// if ANYTHING in the UI thread requires this lock (recurring timer),
// you've just eliminated ANY benefit to having this on a separate thread
lock (myLock)
{
// processor intensive code
}
}
}
catch
{
// handle exceptions
}
}