Calling async method on button click
You're the victim of the classic deadlock. task.Wait()
or task.Result
is a blocking call in UI thread which causes the deadlock.
Don't block in the UI thread. Never do it. Just await
it.
private async void Button_Click(object sender, RoutedEventArgs
{
var task = GetResponseAsync<MyObject>("my url");
var items = await task;
}
Btw, why are you catching the WebException
and throwing it back? It would be better if you simply don't catch it. Both are same.
Also I can see you're mixing the asynchronous code with synchronous code inside the GetResponse
method. StreamReader.ReadToEnd
is a blocking call --you should be using StreamReader.ReadToEndAsync
.
Also use "Async" suffix to methods which returns a Task or asynchronous to follow the TAP("Task based Asynchronous Pattern") convention as Jon says.
Your method should look something like the following when you've addressed all the above concerns.
public static async Task<List<T>> GetResponseAsync<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = await strReader.ReadToEndAsync();
return JsonConvert.DeserializeObject<List<T>>(text);
}
How do i call an async method from a winforms button click event?
Your button_Click
method needs to be async
. Place a async
between private
and void
.
private async void button_Click(object sender, EventArgs e)
{
await LongOperation();
}
Execute async method on button click in blazor
You need to call the Delete
method properly and make it return Task
instead of void
:
<button onclick="@(async () => await Delete(person.Id))">❌</button>
@functions {
// ...
async Task Delete(Guid personId)
{
await this.PersonRepository.Delete(personId);
}
}
How to call async function inside a onClick (Button Click)
javascript is asynchrone and mono-thread. Forget about await
and async
.
From your popup HTML template, you have to bind a function when the user click on the button "I understand". That all.
Your function activateLoadingOverlay2()
should register an event listener of the "I understand" button to do what you want.
How to call an async function on button click in javascript from svelte?
When I copy your code into a REPL as is, the number is generated immediately AND on button click. Which is what is expected and should happen indeed.
What is the best way to call the async function so that the json is only fetched on button click?
Well, don't call it before you need it. Not at component creation, if it's not what you want. You can simply have:
let promise
This would display "The number is undefined".
You can wrap this into an if
if you want to show the text only when there's something happening:
<button on:click={handleClick}>
generate random number
</button>
<button on:click={() => { promise = null }}>
reset
</button>
{#if promise != null}
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
{/if}
Or you can give a non-Promise initial value to your variable if you prefer:
let promise = 0
Or even a promise one if you want:
let promise = Promise.resolve(42)
Calling async function on javascript onclick (or any) events
Hi Suz try the following code it is working for me.
function feedReducer(args){
return new Promise((res,rej)=>{
res(args);
})
}
const somefunction = async (...args) => {
let result = await feedReducer(args);
console.log(result);
// do something
}
somefunction('hello');
Uncaught SyntaxError: await is only valid in async function
the above error you got suggests that your feedReducer is not an async function
Make sure the feedReducer returns a Promise. Good luck
Executing async method on button click Blazor Server
For anyone that comes around to this on google, i ended up setting the button to redirect to a different page that runs the code and redirects to the final page.
<div class="button">
<a href="/enroll/@cor.CourseId">Enroll</a>
</div>
@page "/enroll/{course}"
@inject Data.CourseData _db
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject Microsoft.AspNetCore.Identity.UserManager<Microsoft.AspNetCore.Identity.IdentityUser> userManager
@using System.Security.Claims
@code {
[Parameter]
public string course { get; set; }
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = await userManager.GetUserAsync(authState.User);
if (user != null)
{
string userid = user.Id;
await _db.EnrollCourse(Int32.Parse(course), userid);
NavigationManager.NavigateTo("/course/" + Int32.Parse(course));
}
}
}
How to use async function to await user input from onClick?
Below I made a working solution following the Angular best practices, the code is commented to help you understand it better.
Demo
Template
<input #yourData id="data" type="text" id="input" value=""/>
<button type="button" (click)="onClick()" id="btn">Search</button>
Component
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
import { HttpClient } from "@angular/common/http";
@Component({ ... })
export class YourComponent implements OnInit {
data: any; // The api response is going to be stored here
baseUrl: string = 'https://api.url.info/feed/';
// You need to import the HttpClientModule on your module (in the AppModule is fine)
constructor(private http: HttpClient) { }
// One of the proper ways to access
// Documentation: https://angular.io/api/core/ViewChild
@ViewChild("yourData", { static: true }) yourTemplateElement: ElementRef<HTMLInputElement>;
// Use ngOnInit if the static option is set to true, use ngAfterViewInit otherwise
async ngOnInit() {
this.data = await this.getData(this.baseUrl);
}
getData(url: string): any {
// Use the http client service to make http calls.
// By default it returns an observable but since you want to use
// the async/await keywords, we need to convert it into a promise
return this.http.get(url).toPromise();
}
async onClick() {
const urlSegment = this.yourTemplateElement.nativeElement.value;
this.data = await this.getData(this.baseUrl + urlSegment);
}
}
Is it possible to await async tasks during a button click?
Since event handlers for controls typically return void
, you need to handle this in a different manner. This often means, in a scenario like yours, that you need to disable all or part of your UI while things are loading, i.e.:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
// Make the "list" disabled, so the user can't "select an item" and cause an error, etc
DisableUI();
try
{
// Run your operation asynchronously
await ViewModel.CreateMessageCommand();
}
finally
{
EnableUI(); // Re-enable everything after the above completes
}
}
Related Topics
How to Create Byte Array from Httppostedfile
How to Update a Cell Value in a Db Table, Using SQL Server Ce and C# (Visual Studio 2010)
Can a Tcp C# Client Receive and Send Continuously/Consecutively Without Sleep
Ftp Directory Partial Listing with Wildcards
Mvc: Where to Put Business Logic
How to Select a Random Value from an Enumeration
Is There a Faster Way Than This to Find All the Files in a Directory and All Sub Directories
Working with C# Anonymous Types
How to Use Font Awesome Icons in Project as an Icon of Imagebutton
Automatic Cookie Handling C#/.Net Httpwebrequest+Httpwebresponse
Total Number of Items Defined in an Enum
How to Open a Web Page from My Application
Factory Pattern in C#: How to Ensure an Object Instance Can Only Be Created by a Factory Class
Wpf Webbrowser Mouse Events Not Working as Expected
Wait for Response from the Serial Port and Then Send Next Data
Getting Correct Image Rotation
Run the Current Application as Single Instance and Show the Previous Instance