Ho un metodo asincrono che ottiene i dati API da un server. Quando eseguo questo codice sul mio computer locale, in un'app console, funziona ad alta velocità, passando attraverso alcune centinaia di chiamate http nella funzione asincrona al minuto. Quando metto lo stesso codice per essere attivato da un messaggio di coda WebJob di Azure, tuttavia, sembra funzionare in modo sincrono e i miei numeri scorrono - sono sicuro che mi manca qualcosa di semplice nel mio approccio - ogni assistenza è apprezzata.Come fare Async nella funzione WebJob di Azure
(1) .. WebJob funzione che ascolta per un messaggio sulla coda e prende il via l'API ottenere il processo sul messaggio ricevuto:
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static async Task ProcessQueueMessage ([QueueTrigger("myqueue")] string message, TextWriter log)
{
var getAPIData = new GetData();
getAPIData.DoIt(message).Wait();
log.WriteLine("*** done: " + message);
}
}
(2) la classe che le opere al di fuori azzurro in modalità asincrona a velocità ...
class GetData
{
// wrapper that is called by the message function trigger
public async Task DoIt(string MessageFile)
{
await CallAPI(MessageFile);
}
public async Task<string> CallAPI(string MessageFile)
{
/// create a list of sample APIs to call...
var apiCallList = new List<string>();
apiCallList.Add("localhost/?q=1");
apiCallList.Add("localhost/?q=2");
apiCallList.Add("localhost/?q=3");
apiCallList.Add("localhost/?q=4");
apiCallList.Add("localhost/?q=5");
// setup httpclient
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 10000000 };
var timeout = new TimeSpan(0, 5, 0); // 5 min timeout
client.Timeout = timeout;
// create a list of http api get Task...
IEnumerable<Task<string>> allResults = apiCallList.Select(str => ProcessURLPageAsync(str, client));
// wait for them all to complete, then move on...
await Task.WhenAll(allResults);
return allResults.ToString();
}
async Task<string> ProcessURLPageAsync(string APIAddressString, HttpClient client)
{
string page = "";
HttpResponseMessage resX;
try
{
// set the address to call
Uri URL = new Uri(APIAddressString);
// execute the call
resX = await client.GetAsync(URL);
page = await resX.Content.ReadAsStringAsync();
string rslt = page;
// do something with the api response data
}
catch (Exception ex)
{
// log error
}
return page;
}
}
Hai provato a cambiare "getAPIData.DoIt (messaggio) .Wait();" "attendi getAPIData.DoIt (messaggio);"? –
Grazie Jason - i tuoi e altri commenti qui mi hanno aiutato a farlo funzionare. Molto apprezzato. – qtime67