繁体   English   中英

异步方法无法正常工作

[英]Async method doesn't work as expected

我正在制作测试控制台应用程序,该应用程序将使用URL下载流mp4。

我使用了MSDN上发布的异步示例。

下面是代码。

 class Program
{
    public static ManualResetEvent allDone = new ManualResetEvent(false);
    const int BUFFER_SIZE = 1024;
    public static int total = 0;

    static void Main(string[] args)
    {

        Uri httpSite = new Uri("URI");

        WebRequest wreq = WebRequest.Create(httpSite);

        RequestState rs = new RequestState();

        rs.Request = wreq;

        IAsyncResult r = (IAsyncResult)wreq.BeginGetResponse(
           new AsyncCallback(RespCallback), rs);

        allDone.WaitOne();
        FileStream file = new FileStream("test.mp4", FileMode.Append);
        file.Write(rs.data.ToArray(), 0, rs.data.Count());
        Console.ReadKey();

    }

    private static void RespCallback(IAsyncResult ar)
    {
        // Get the RequestState object from the async result.
        RequestState rs = (RequestState)ar.AsyncState;

        // Get the WebRequest from RequestState.
        WebRequest req = rs.Request;

        // Call EndGetResponse, which produces the WebResponse object
        //  that came from the request issued above.
        WebResponse resp = req.EndGetResponse(ar);

        //  Start reading data from the response stream.
        Stream ResponseStream = resp.GetResponseStream();

        // Store the response stream in RequestState to read 
        // the stream asynchronously.
        rs.ResponseStream = ResponseStream;

        //  Pass rs.BufferRead to BeginRead. Read data into rs.BufferRead
        IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0,
           BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
    }
    private static void ReadCallBack(IAsyncResult asyncResult)
    {
        // Get the RequestState object from AsyncResult.
        RequestState rs = (RequestState)asyncResult.AsyncState;

        // Retrieve the ResponseStream that was set in RespCallback. 
        Stream responseStream = rs.ResponseStream;

        // Read rs.BufferRead to verify that it contains data. 
        int read = responseStream.EndRead(asyncResult);
        if (read > 0)
        {
            // Prepare a Char array buffer for converting to Unicode.
            byte[] charBuffer = new byte[BUFFER_SIZE];             


            responseStream.Read(charBuffer, 0, read);
            rs.data.AddRange(charBuffer);


            IAsyncResult ar = responseStream.BeginRead(
               rs.BufferRead, 0, BUFFER_SIZE,
               new AsyncCallback(ReadCallBack), rs);
        }
        else
        {               
            responseStream.Close();
            // Set the ManualResetEvent so the main thread can exit.
            allDone.Set();
        }
        return;
    }
}

当我使用这种异步方法时,保存的文件大小为1356KB,而该文件的大小应为2409KB。

在responseStream.close()上的断点被击中之后,我可以在IF(read> 0)语句中找到断点。 这是因为它读取0长度,然后读取更多吗?

当我使用如下所示的非异步方法时,我可以成功下载文件。

  public static void StreamDownload(string url)
    {
        int dataLength;
        int bytesRead;

        WebRequest req = WebRequest.Create(url);
        WebResponse response = req.GetResponse();
        string fileName = System.IO.Path.GetFileName("test.mp4");

        Stream dataStream = response.GetResponseStream();

        byte[] buffer = new byte[1024];

        FileStream file = new FileStream(fileName, FileMode.Append);

        dataLength = (int)response.ContentLength;

        do
        {
            bytesRead = dataStream.Read(buffer, 0, buffer.Length);
            file.Write(buffer, 0, bytesRead);

        } while (bytesRead != 0);


    }

有谁知道我为什么用异步方法失败了?

谢谢你的帮助。

有多种其他下载文件的方法,它们更为简单 ,您应该选择其中一种。

webclient vs httpclient vs httpwebrequest

在您的情况下,我建议HttpClient

public static async Task DownloadAsync(string requestUri, string filename)
{
    using (var httpClient = new HttpClient())
    {
        using (var fs = File.OpenWrite(filename))
        {
            await (await httpClient.GetStreamAsync(requestUri)).CopyToAsync(fs);
        }
    }
}

或者,如果需要显示一些进度,则可以使用WebClient类的DownloadFileAsync方法,但是上面的示例更简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM