Runtime error and program exit when using - Async and await using C #
I am trying to use the concept of async and wait in my program. The program exits abruptly. I am trying to get content length from multiple random urls and process them and display the size in bytes of each url.
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace TestProgram
{
public class asyncclass
{
public async void MainCall() {
await SumPageSizes();
}
public async Task SumPageSizes(){
List<string> urllist = GetUrlList();
foreach (var url in urllist)
{
byte[] content = await GetContent(url);
Displayurl(content, url);
}
}
private void Displayurl(byte[] content, string url)
{
var length = content.Length;
Console.WriteLine("The bytes length for the url response " + url + " is of :" +length );
}
private async Task<byte[]> GetContent(string url)
{
var content = new MemoryStream();
try
{
var obj = (HttpWebRequest)WebRequest.Create(url);
WebResponse response = obj.GetResponse();
using (Stream stream = response.GetResponseStream())
{
await stream.CopyToAsync(content);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
return content.ToArray();
}
private List<string> GetUrlList()
{
var urllist = new List<string>(){
"http://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"http://msdn.microsoft.com",
"http://msdn.microsoft.com/en-us/library/hh290136.aspx",
"http://msdn.microsoft.com/en-us/library/ee256749.aspx",
"http://msdn.microsoft.com/en-us/library/hh290138.aspx",
"http://msdn.microsoft.com/en-us/library/hh290140.aspx",
"http://msdn.microsoft.com/en-us/library/dd470362.aspx",
"http://msdn.microsoft.com/en-us/library/aa578028.aspx",
"http://msdn.microsoft.com/en-us/library/ms404677.aspx",
"http://msdn.microsoft.com/en-us/library/ff730837.aspx"
};
return urllist;
}
}
}
home
public static void Main(string[] args)
{
asyncclass asyncdemo = new asyncclass();
asyncdemo.MainCall();
}
source to share
The problem is that you are not expecting an asynchronous method and therefore you terminate the application before the method completes.
In C # 7, you can create an async entry point that allows the wait keyword.
public static async Task Main(string[] args)
{
asyncclass asyncdemo = new asyncclass();
await asyncdemo.MainCall();
}
If you want to bubble your exceptions out MainCall
, you need to change the return type to Task
.
public async Task MainCall()
{
await SumPageSizes();
}
If you want to run asynchronous code before C # 7, you can do the following.
public static void Main(string[] args)
{
asyncclass asyncdemo = new asyncclass();
asyncdemo.MainCall().Wait();
// or the following line if `MainCall` doesn't return a `Task`
//Task.Run(() => MainCall()).Wait();
}
source to share
MainCall
returns an unfinished task and there is no other line of code besides it, so your program ends
Expect to use:
asyncdemo.MainCall().Wait();
You need to avoid async void
and change MainCall
to async Task
to be able to wait for it from the caller.
Since it is similar to a console application, you can not use await
, and async
for the method of Main
using the current version of the compiler (I think the discussion for the upcoming implementation of C # 7).
source to share
You have to be very careful when using async void methods. They don't wait. One normal example of asynchronous void is when you call an expected method inside a button click:
private async void Button_Click(object sender, RoutedEventArgs e)
{
// run task here
}
This way, the UI won't get stuck waiting for the button click to complete. In most custom methods, you almost always want to return a task so you can know when your method has completed.
source to share