Calling Async Method on Button Click

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



Leave a reply



Submit