i am calling an asmx service from my windows form application in a background worker. i want to be able to cancel/stop the call once a button is pressed.
i am currently performing the following:
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GlobalVariables.worker = sender as BackgroundWorker;
try
{
if (GlobalVariables.worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
e.Result = CallServer(ServerName, ActionName); // call on a web method in the referenced service
}
}
catch (Exception ee)
{
GlobalFunctions.ShowError(ee);
}
}
private void button1_Click(object sender, EventArgs e) //button to cancel the call
{
if (GlobalVariables.worker.IsBusy == true)
{
//GlobalVariables.worker.thre;
GlobalVariables.worker.CancelAsync();
GlobalVariables.worker.Dispose();
}
//GlobalVariables.worker.CancelAsync();
Form1.f.Enabled = true;
Form1.f.progressBar1.Text = "Done!";
Form1.f.progressBar1.Visible = false;
Form1.f.textBox1.Visible = true;
Close();
}
the following doesnt seem to work because when i press on cancel, the web method called in the service reference is not stopped and still returns data
You can make client react immediately to the Abort button by using a Task and a CancellationToken. The client will do its best to abort the call, but the server will continue execution of the call unless it does something special about that.
Here is the code of the client side:
public partial class Form1 : Form
{
private CancellationTokenSource _cancellationTokenSource;
private WebService1SoapClient _client;
public Form1()
{
InitializeComponent();
btnAbort.Enabled = false;
}
private void btnCall_Click(object sender, EventArgs e)
{
btnCall.Enabled = false;
btnAbort.Enabled = true;
lblStatus.Text = "CALLING SERVER...";
_cancellationTokenSource = new CancellationTokenSource();
_cancellationTokenSource.Token.Register(() => backgroundWorker1.CancelAsync());
backgroundWorker1.RunWorkerAsync();
}
private void btnAbort_Click(object sender, EventArgs e)
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
try
{
_client = new WebService1SoapClient();
var call = CallServerAsync("ServerName", "ActionName");
call.Wait(_cancellationTokenSource.Token);
e.Result = call.Result;
}
catch (TaskCanceledException)
{
e.Cancel = true;
_client.Abort();
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnCall.Enabled = true;
btnAbort.Enabled = false;
lblStatus.Text = (e.Error != null ? "CALL FAILED: " + e.Error.Message : "CALL COMPLETED!");
}
private async Task<string> CallServerAsync(string serverName, string actionName)
{
var response = await _client.HelloWorldAsync();
return response.Body.HelloWorldResult;
}
}
thanks to #felix-b answer , i did the following:
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GlobalVariables.worker = sender as BackgroundWorker;
try
{
if (GlobalVariables.worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
Object callResponse = CallServer(ServerName, ActionName);
if (GlobalVariables.worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
e.Result = callResponse;
}
}
}
catch (Exception ee)
{
e.Cancel = true;
if (ee.GetType().IsAssignableFrom(typeof(System.ServiceModel.CommunicationObjectAbortedException)))
{
MessageBox.Show("The Request Was Cancelled");
}
else
{
GlobalFunctions.ShowError(ee);
}
}
}
public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{}
else
{
//continue
}
}
private void button1_Click(object sender, EventArgs e)
{
if (GlobalVariables.worker.IsBusy == true)
{
server.abort(); //service reference
GlobalVariables.worker.CancelAsync();
GlobalVariables.worker.Dispose();
}
}
Related
how i can make a loop timer that check if in main form topmost.enable is false until a label is visible and then set to true when the label deactive?
If tried this code but not work:
private void InitializeAlive()
{
alive = new System.Timers.Timer();
alive.Interval = 1000;
alive.AutoReset = true;
alive.Elapsed += Alive_Tick;
alive.Start();
}
private void Alive_Tick(object sender, EventArgs e)
{
if (lblPassword.Enabled)
{
this.TopMost = false;
}
else
{
this.TopMost = true;
alive.Dispose();
}
}
private void btnPrint_Click(object sender, EventArgs e)
{
if (txtPassword.Text == pswd)
{
TopMost = false;
webPrintSetting.ShowPageSetupDialog();
InitializeAlive();
}
else
{
btnPrint.Enabled = false;
btnPrint.Visible = false;
lblPassword.Visible = false;
txtPassword.Enabled = false;
txtPassword.Visible = false;
txtPassword.Clear();
}
}
If you only need to do something when 'Enabled' property of the label changes, then you can simply add handler to the 'EnabledChanged' property, like this:
public Form1()
{
InitializeComponent();
lblPassword.EnabledChanged += new System.EventHandler(this.LblPassword_EnabledChanged);
}
And implement the handler like this:
private void LblPassword_EnabledChanged(object sender, EventArgs e)
{
TopMost = !lblPassword.Enabled;
}
I find a solution to toggle on/off topmost (off until a target process is running).
private Timer check;
public MyForm()
{
InitializeCheck();
}
private void InitializeCheck()
{
check = new Timer();
check.Interval = 5000;
check.Tick += Check_Tick;
check.Enabled = false;
}
private void Check_Tick(object sender, EventArgs e)
{
CheckProgram();
}
private void CheckProgram()
{
Process[] program = rocess.GetProcessesByName("notepad");
if (program.Length == 0)
{
check.Enabled = false;
TopMost = true;
}
private void button1_Click(object sender, EventArgs e)
{
TopMost = false;
check.Enabled = true;
}
I trying to do an inteface to monitoring the Serial Port. I am using Visual forms. So, I had created a combobox to select the PortCOM, a TextBox to send the data to Serial Port and a TextBoxReceber to receive the Serial Data. I trying print the data received in the TextBoxReceber, I'm using the AppendText but I haven't sucess. Anybody can help me?
My Form1.cs is:
namespace ConsoleESP
{
public partial class Form1 : Form
{
string RxString = "";
public Form1()
{
InitializeComponent();
timerCOM.Enabled = true;
atualizaCOMs();
}
private void atualizaCOMs()
{
int i = 0;
bool quantDif = false;
if (comboBox1.Items.Count == SerialPort.GetPortNames().Length)
{
foreach (string s in SerialPort.GetPortNames())
{
if (comboBox1.Items[i++].Equals(s) == false)
{
quantDif = true;
}
}
}
else quantDif = true;
if (quantDif == false) return;
comboBox1.Items.Clear();
foreach(string s in SerialPort.GetPortNames())
{
comboBox1.Items.Add(s);
}
comboBox1.SelectedIndex = 0;
}
private void timerCOM_Tick(object sender, EventArgs e)
{
atualizaCOMs();
}
private void btConnect_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == false)
{
try
{
serialPort1.PortName = comboBox1.Items[comboBox1.SelectedIndex].ToString();
serialPort1.Open();
}
catch
{
return;
}
if (serialPort1.IsOpen)
{
btConnect.Text = "Desconectar";
comboBox1.Enabled = false;
}
}
else
{
try
{
serialPort1.Close();
comboBox1.Enabled = true;
btConnect.Text = "Conectar";
}
catch
{
return;
}
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialPort1.IsOpen == true) serialPort1.Close();
}
private void btEnviar_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen == true)
serialPort1.Write(textBoxEnviar.Text);
}
private delegate void RefreshTextBox();
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting();
this.Invoke(new EventHandler(TrataDadoRecebido));
}
private void TrataDadoRecebido(object sender, EventArgs e)
{
textBoxReceber.AppendText(RxString);
}
}
}
Okay, this is my whole code. Now... Detail_BeforePrint() will be called first, and xrPictureBox8_BeforePrint second.
Now I want to call Detail_BeforePrint e.Cancel = true; inside the else in xrPictureBox8_BeforePrint event.
private void Detail_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
//here should e.Cancel = true be if it came from xrPictureBox_BeforePrint()
}
private void xrPictureBox8_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
try
{
if (xrPictureBox8.ImageUrl.Length > 0) { }
else
{
Detail_BeforePrint(null,[call Cancel parameter]);
}
}
catch (Exception)
{
}
}
Maybe something like this would help?
private void Detail_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
DoDetail_BeforePrint(e, false);
}
private void DoDetail_BeforePrint(System.Drawing.Printing.PrintEventArgs e, bool cancel)
{
if (cancel) e.Cancel = true;
//other things
}
private void xrPictureBox8_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
try
{
if (xrPictureBox8.ImageUrl.Length > 0) { }
else
{
DoDetail_BeforePrint(e, true);
//or just call e.Cancel = true here?
}
}
catch (Exception)
{
}
}
how to make that ongoing actions WebBrowserDocumentCompleted worked in a separate thread. And so it does not affect the main form (not hang the entire application)
Form1
private void bStart_Click(object sender, EventArgs e)
{
wb.Navigate("http://www.moswar.ru");
}
Form2
public void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
wb = sender as WebBrowser;
ThreadPool.QueueUserWorkItem(new WaitCallback((object unused) =>
{
if (wb.Document.GetElementById("login-email") != null)
{
wb.Document.GetElementById("login-email").InnerText = "myemail#blah.pe";
wb.Document.GetElementById("login-password").InnerText = "MyPassword";
GetElementsByClassName(new string[] { "button luxury" })[0].InvokeMember("click");
}
if (e.Url.AbsoluteUri == "http://www.moswar.ru/player/" || e.Url.AbsoluteUri == "http://www.moswar.ru/player/#login")
{
wb.Navigate("http://www.moswar.ru/metro/");
}
}));
//and so on .....
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate
{
MessageBox.Show("hi");
}
}
How I can replay a video in Windows Media control? I try to do it by this way? but it doesn't work
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, System.EventArgs e)
{
//mediaPlayer.currentPlaylist = mediaPlayer.mediaCollection.getByName("Dastan");
//mediaPlayer.URL = #"C:\Documents and Settings\Администратор\Мои документы\Моя музыка\Мои списки воспроизведения\Dastan.wpl";
//mediaPlayer.uiMode = "none";
PlayFile(#"C:\Documents and Settings\Администратор\Мои документы\Моя музыка\Мои списки воспроизведения\Dastan.wpl");
}
private void mediaPlayer_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if ((WMPLib.WMPPlayState)e.newState == WMPPlayState.wmppsPlaying)
{
mediaPlayer.fullScreen = true;
mediaPlayer.Ctlenabled = false;
}
else if ((WMPLib.WMPPlayState)e.newState == WMPPlayState.wmppsMediaEnded)
{
Form1_Load(null, null);
}
}
private void PlayFile(String url)
{
mediaPlayer.URL = url;
mediaPlayer.Ctlcontrols.play();
}
Any ideas?
mediaPlayer.settings.setMode("loop", true);
This code snippet does all job. Thanks for answers..
Try setting mediaPlayer.Ctlcontrols.currentPosition to 0.
private void mediaPlayer_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if ((WMPLib.WMPPlayState)e.newState == WMPPlayState.wmppsPlaying)
{
mediaPlayer.fullScreen = true;
mediaPlayer.Ctlenabled = false;
}
else if ((WMPLib.WMPPlayState)e.newState == WMPPlayState.wmppsMediaEnded)
{
mediaPlayer.Ctlcontrols.currentPosition = 0;
mediaPlayer.Ctlcontrols.play();
}
}