How to know if an async method is running - c#

I have a button that on click event goes and get data from server and displays that on a grid.
The code is like below:
private void btnSearch_Click(object sender, EventArgs e)
{
// Here I should do something in order to know if the async ProcessSearch method is busy..
// if not busy then I will execute it if not then I will return.
// shows loading animation
ShowPleaseWait(Translate("Searching data. Please wait..."));
ProcessSearch();
}
private async void ProcessSearch()
{
Data.SeekWCF seekWcf = new Data.SeekWCF();
_ds = await seekWcf.SearchInvoiceAdminAsync(new Guid(cboEmployer.Value.ToString()), new Guid(cboGroup.Value.ToString()), txtSearchInvoiceNumber.Text, chkSearchLike.Checked, txtSearchFolio.Text, Convert.ToInt32(txtYear.Value));
seekWcf.Dispose();
if (_ds != null)
{
SetupInvoiceGrid();
}
// hides the loading animation
HidePleaseWait();
}
How can I know if the async method ProcessSearch is busy or running so I can prevent the user to execute the method again when clicking the button again.

You could just set a boolean:
private bool isSearching = false;
private void btnSearch_Click(object sender, EventArgs e)
{
if (isSearching)
return;
// shows loading animation
ShowPleaseWait(Translate("Searching data. Please wait..."));
ProcessSearch();
}
private async void ProcessSearch()
{
isSearching = true;
// do other stuff
isSearching = false;
}
If you're concerned about concurrency, you could add a lock:
private bool isSearching = false;
private object lockObj = new object();
private void btnSearch_Click(object sender, EventArgs e)
{
lock (lockObj)
{
if (isSearching)
return;
else
isSearching = true;
}
// shows loading animation
ShowPleaseWait(Translate("Searching data. Please wait..."));
ProcessSearch();
}
private async void ProcessSearch()
{
// do other stuff
isSearching = false;
}

Related

GO to onother task with butten clicked

I have an entry_TextChanged event handler and a button.
How can I say if this button clicked go to that entry_TextChanged handler again?
private bool save = false;
private void entry_TextChanged(object sender, TextChangedEventArgs e)
{
if (save == true)
{
// Do Something
}
}
private void goto_Clicked(object sender, EventArgs e)
{
save = true;
// GO and do the entry texchanged??
}
you can just call it the same as any other function entry_TextChanged(null, null) or any other values that you want to send to the function
private void goto_Clicked(object sender, EventArgs e)
{
save = true;
entry_TextChanged(null, null)
}

Return a value from a uwp usercontrol

A UWP UserControl with 2 buttons
public sealed partial class SaveChangesUserControl : UserControl
{
public bool CanGo { get; set; }
public SaveChangesUserControl()
{
InitializeComponent();
}
private void Leave(object sender, EventArgs e)
{
CanGo = true;
}
private void Stay(object sender, EventArgs e)
{
CanGo = false;
}
}
SaveChangesUserControl will be in a xaml page. I can bind the visibility to a property in the xaml page. Leave and Stay are event handlers for buttons in SaveChangesUserControl. How do I capture CanGo as the return value of SaveChangesUserControl?
Something like bool canGo = SaveChangesUserControl would be nice.
Like a ContentDialog, but not a ContentDialog
You could use AutoResetEvent class to do a thread synchronization. When signaled, reset automatically after releasing a single waiting thread.
Please check the following code:
SaveChangesUserControl.xaml.cs
private static AutoResetEvent Locker = new AutoResetEvent(false);
public async Task<bool> ShowAsync()
{
Visibility = Visibility.Visible;
await Task.Run(() => {
Locker.WaitOne(); //Wait a singal
});
return CanGo;
}
private void Leave(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
CanGo = true;
Locker.Set(); //Release a singal
}
private void Stay(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
CanGo = false;
Locker.Set(); //Release a singal
}
MainPage.xaml.cs
private async void Button_Click(object sender, RoutedEventArgs e)
{
var t = await myUserControl.ShowAsync(); //Call the method, you could get a return value after you click on user control
}

How to access the task status runnning in a button clicking event from the other button clicking event

I want to know the the task status runnning in A button event from the other button click.
Like this.
private void button1_Click(object sender, EventArgs e)
{
Task.Run(()=>{
//The method to take long time
//For example
Thread.Sleep(5000)
;});
}
private coid button2_Click(object sender, EventArgs e)
{
//until 5000ms
//the method to know the above task status (Runnning....)
//after 5000ms
//the method to know the above task status (Conpleted....)
}
It's not entirely clear what you're trying to achieve, but if you want to check the status of the task, you can get its reference when calling Task.Run()
private Task _task;
private void button1_Click(object sender, EventArgs e)
{
_task = Task.Run(() => Thread.Sleep(5000));
}
private void button2_Click(object sender, EventArgs e)
{
if (_task?.Status == TaskStatus.RanToCompletion)
//do something
}
The answer is as vague as the question, so if you could give me a bit more details, I could come up with a better more tailored answer.
Again, it's very unclear what you're looking for here...but this is an expanded version of Faylit's example:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Task T = null;
private void Form1_Load(object sender, EventArgs e)
{
updateStatus();
}
private async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
await (T = Task.Run(() =>
{
updateStatus();
System.Threading.Thread.Sleep(5000);
}));
button1.Enabled = true;
updateStatus();
}
private void button2_Click(object sender, EventArgs e)
{
updateStatus();
}
private void updateStatus()
{
if (label1.InvokeRequired)
{
label1.Invoke((MethodInvoker)delegate
{
updateStatus();
});
}
else
{
if (T == null)
{
label1.Text = "Task not started.";
}
else if (!T.IsCompleted)
{
label1.Text = "Task running...";
}
else
{
label1.Text = "Task completed.";
}
}
}
}
It might give you some more ideas.

Posting webBrowser1_DocumentCompleted keeps looping

I have written some code to post messages to a site. It works just fine (for the first instance), the problem is that it keeps looping (running the SendData method over and over) once it is in the webBrowser1_DocumentCompleted method. So I must not be handling the event correctly. After it has run the SendData call one time I want it return to the button1_Start_Click event from which it originally started.
private void button1_Start_Click(object sender, EventArgs e)
{
GetData();
}
private void GetData()
{
webBrowser1.Navigate(inputURLID);
}
private void SendData()
{
webBrowser1.Document.GetElementById("subject").SetAttribute("value", textBox2_Subject.Text);//To (username)
webBrowser1.Document.GetElementById("message").SetAttribute("value", richTextBox1.Text);//Subject
webBrowser1.Document.GetElementById("Submit").InvokeMember("click");//Message
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
SendData();
}
I'll have to post, the answer you selected is going to get you in deep trouble. The workaround is simple, you just need a variable that tells you that the next DocumentCompleted event is the one you are interested in. Like this:
private bool WaitingForData;
private void GetData()
{
webBrowser1.Navigate(inputURLID);
WaitingForData = true;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (WaitingForData) SendData();
WaitingForData = false;
}
The problem is that when you do the click on Submit, a new page is loaded and DocumentCompleted is called again for this new page.
You can try something like this:
bool documentCompleted = false;
private void button1_Start_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(inputURLID);
WaitForDocumentCompleted();
SendData();
WaitForDocumentCompleted();
}
private void WaitForDocumentCompleted()
{
while (!documentCompleted)
{
Thread.Sleep(100);
Application.DoEvents();
}
documentCompleted = false;
}
private void SendData()
{
webBrowser1.Document.GetElementById("subject").SetAttribute("value", textBox2_Subject.Text);//To (username)
webBrowser1.Document.GetElementById("message").SetAttribute("value", richTextBox1.Text);//Subject
webBrowser1.Document.GetElementById("Submit").InvokeMember("click");//Message
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
documentCompleted = true;
}

break onclick event from method

Button's OnClick event is called:
private void vkb7_Click_1(object sender, EventArgs e)
{
//method
button_start(object sender);
// do stuff 2
}
Some method is triggered:
private void button_start(object sender)
{
bool some = true;
if (some)
{
return; // I'd also like to break "button click"
}
}
I'd like to break "button click" event from method - how do I do it?
Simple, let button_start() return a boolean:
private bool button_start(object sender)
{
bool some = ...;
return some;
}
private void vkb7_Click_1(object sender, EventArgs e)
{
//method
if (button_start(object sender))
return;
// do stuff 2
}
If you are determining in button_start whether actions should occur in vkb7_Click_1, consider making button_start return bool and then use the return value in vkb7_Click_1.
On the other hand, if you are encountering an error condition in button_start, throw an exception.
You can't really "block" the event as it has already been fired. You can however handle the click manually depending on the result.
private void vkb7_Click_1(object sender, EventArgs e)
{
bool result = button_start(sender);
if (result)
DoSomething();
else
DoSomethingElse();
}
private bool button_start(object sender)
{
bool some = true;
if (some)
return false;
return true;
}
First, Set the return type of button_start to bool
Second, If you want to pass sender of vkb7 button or properties of vkb7 button,
Then you should pass it like this:
button_start(sender)
So the code would be like this:
private void vkb7_Click_1(object sender, EventArgs e)
{
//method
if(button_start(sender))
// do stuff 2
}
Then in the method
private bool button_start(object sender)
{
bool some = true;
if (some)
{
return true; // I'd also like to break "button click"
}
else
return false;
}

Categories