Jump to content




Recent Status Updates

View All Updates

Binpress - Cut your development time and costs in half
Photo
- - - - -

Problem with async method

c# async

This topic has been archived. This means that you cannot reply to this topic.
11 replies to this topic

#1 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 05 March 2013 - 06:54 PM

This is my current code:

 

public static void DownloadFile(string _url, string _destination)
        {
            //Method for downloading files from the internet
            //First argument is a full link from the internet where that file is stored
            //Second argument is a full destination where user wants to store that downloaded file with file extension
           
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
            request.Timeout = 5000;

            
                using (WebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (FileStream stream = new FileStream(_destination, FileMode.Create, FileAccess.Write))
                    {
                        response.GetResponseStream().CopyTo(stream);
                    }
                    response.Close();
                }            
        }

        public static async void DownloadFileAsync(string _url, string _destination)
        {
                await Task.Run(() => DownloadFile(_url, _destination));
        }

 

And when I use just DownloadFile method in my main application, everything is working fine. But when I use DownloadFileAsync method it just creates my pdf file but it has 0 kB. Can anyone tell me what am I doing wrong?


Microsoft Student Partner, Microsoft Certified Professional


#2 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 708 posts

Posted 07 March 2013 - 12:07 PM

Are you waiting until its done?

Creating SEGFAULTs since 1995.


#3 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 08 March 2013 - 04:24 AM

Yes


Microsoft Student Partner, Microsoft Certified Professional


#4 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 708 posts

Posted 08 March 2013 - 04:42 AM

What does the calling code look like?

Creating SEGFAULTs since 1995.


#5 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 08 March 2013 - 08:37 AM

With C# 5.0 feature (async/await) there is no calling code or anything else. Where ever I read, they said that everything is replaced with async and await keywords. That't the feature in C# 5.0


Microsoft Student Partner, Microsoft Certified Professional


#6 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 708 posts

Posted 08 March 2013 - 11:12 AM

From what I read, the await keyword doesn't block:

 

"An await expression does not
block the thread on which it is executing. Instead, it causes the
compiler to sign up the rest of the async method as a continuation on
the awaited task. Control then returns to the caller of the async
method. When the task completes, it invokes its continuation, and
execution of the async method resumes where it left off."

 

 

But that doesn't really explain why you get an empty file; is the program a simple console app, so the main thread runs to the end after you try the async download? If so its possible (but admittedly a long shot) that the HttpRequest is being early terminated and returning a response object with no data, that would explain the creation of the file and the lack of data.

 

One way to check would be to sleep the main thread after your async method for some time and see if you get data or not.


Creating SEGFAULTs since 1995.


#7 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 08 March 2013 - 04:06 PM

Yes, it is simple console app. 

 

Now my main code looks like:

 

Stopwatch _sw = new Stopwatch();
            _sw.Start();
            //WebClient _wc = new WebClient();
            //_wc.DownloadFile("file:///H:/NekiPDF.pdf", "H:\\NekiPDF2.pdf");
            CustomNet.CustomNet _cn = new CustomNet.CustomNet();

            _cn.DownloadFileAsync("http://it-ebooks.info/go.php?id=251-1362797948-306af8891577ac42d5ba94d40f1d9b7f", "H:\\NekiPDF10.pdf");
            Thread.Sleep(100000);
            _cn.DownloadCompleted += (sender, e) =>
            {
            };
            //CustomNet.CustomNet.DownloadFile(, "H:\\nekiPDF.pdf");
            _sw.Stop();

            Console.WriteLine("for {0}", _sw.Elapsed);
            Console.ReadKey();

 

And it is working. Is that now what I needed? Is now my method working asynchronouslly? And how can I prevent the user from using Thread.Sleep method so he can just call that async method and everything would work great?


Microsoft Student Partner, Microsoft Certified Professional


#8 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 708 posts

Posted 09 March 2013 - 12:24 AM

well you can prevent the user from using the Thread.Sleep method. But in your case, you have no need to work asyncronously. Since your doing nothing whilst the download is waiting.

 

So your method is working asyncronously; if instead of using thread.sleep, you did some random calculations you'd see that its working.


Creating SEGFAULTs since 1995.


#9 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 09 March 2013 - 03:38 AM

Tnx for your help.


Microsoft Student Partner, Microsoft Certified Professional


#10 AceInfinity

AceInfinity

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 276 posts

Posted 18 March 2013 - 04:02 PM

This wouldn't be a very good use of Thread.Sleep(), since you're using it as a timing thing... You can use it to simulate expensive IO tasks for example, just to test, but it's not meant to be used as a timer for running code.

 

In that last code you have you don't need Thread.Sleep() at all, and you don't have anything in that event handler you're assigning.


Edited by AceInfinity, 18 March 2013 - 04:04 PM.

Microsoft MVP (2012) - .NET Programming | ®Crestron DMC-T Certified Programmer
Posted Image


#11 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,249 posts

Posted 20 March 2013 - 07:52 AM

Another async question.

 

Here is the example from the MSDN:

 

static async void Main()
	{
    try	
    {
      // Create a New HttpClient object.
      HttpClient client = new HttpClient();

      HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
      response.EnsureSuccessStatusCode();
      string responseBody = await response.Content.ReadAsStringAsync();
      // Above three lines can be replaced with new helper method in following line 
      // string body = await client.GetStringAsync(uri);

      Console.WriteLine(responseBody);
    }  
    catch(HttpRequestException e)
    {
      Console.WriteLine("\nException Caught!");	
      Console.WriteLine("Message :{0} ",e.Message);
    }
  }

 

I know that this code will throw the error because Main method can't be called asynchronously because it is runned in Main thread.

But, what I want to know is how can async method return some value if the rule says that async method can be only with this types: void, Task and Task<T>.

 

Now, how can I, based on this rule return some value from the async method?


Microsoft Student Partner, Microsoft Certified Professional


#12 AceInfinity

AceInfinity

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 276 posts

Posted 20 March 2013 - 10:53 AM

Another async question.
 
Here is the example from the MSDN:

static async void Main()
	{
    try	
    {
      // Create a New HttpClient object.
      HttpClient client = new HttpClient();

      HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
      response.EnsureSuccessStatusCode();
      string responseBody = await response.Content.ReadAsStringAsync();
      // Above three lines can be replaced with new helper method in following line 
      // string body = await client.GetStringAsync(uri);

      Console.WriteLine(responseBody);
    }  
    catch(HttpRequestException e)
    {
      Console.WriteLine("\nException Caught!");	
      Console.WriteLine("Message :{0} ",e.Message);
    }
  }
 
I know that this code will throw the error because Main method can't be called asynchronously because it is runned in Main thread.
But, what I want to know is how can async method return some value if the rule says that async method can be only with this types: void, Task and Task<T>.
 
Now, how can I, based on this rule return some value from the async method?


Look into Task<T>.Result.

Edited by AceInfinity, 20 March 2013 - 10:53 AM.

Microsoft MVP (2012) - .NET Programming | ®Crestron DMC-T Certified Programmer
Posted Image





Powered by binpress