网络编程 - 异步调用

    这几天主要是在开发一个《MP3下载器》他的主要功能是:

  1.  通过指定格式的文本文件输入需要下载的歌曲;
  2. 自动在互联网上寻找最优的下载链接;
  3. 自动从最优的下载链接中下载文件到指定的文件夹并自动改名。

    现在就来谈谈我在这个软件开发中遇到的困难及解决的办法:
在软件开发中遇的第一个问题是网络文件的下载,参考网上的一个例子是通过定时来查询下载文件的大小的,这样就导致系统不能精确地计算文件下载情况,后来看到了微软的一个例子使我解决了这个问题:

附:微软的代码

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;



public class RequestState
{
  
// This class stores the state of the request.
  const int BUFFER_SIZE = 1024;
  
public StringBuilder requestData;
  
public byte[] bufferRead;
  
public WebRequest request;
  
public WebResponse response;
  
public Stream responseStream;
  
public RequestState()
  
{
    bufferRead 
= new byte[BUFFER_SIZE];
    requestData 
= new StringBuilder("");
    request 
= null;
    responseStream 
= null;
  }

}

class WebRequest_BeginGetResponse
{
  
public static ManualResetEvent allDone= new ManualResetEvent(false);
  
const int BUFFER_SIZE = 1024;
  
static void Main()
  
{
    
try
    
{
      
// Create a new webrequest to the mentioned URL.   
      WebRequest myWebRequest= WebRequest.Create("http://www.contoso.com");
      
      
// Please, set the proxy to a correct value. 
      WebProxy proxy=new WebProxy("myproxy:80");

      proxy.Credentials
=new NetworkCredential("srikun","simrin123");
      myWebRequest.Proxy
=proxy;
      
// Create a new instance of the RequestState.
      RequestState myRequestState = new RequestState();
      
// The 'WebRequest' object is associated to the 'RequestState' object.
      myRequestState.request = myWebRequest;
      
// Start the Asynchronous call for response.
      IAsyncResult asyncResult=(IAsyncResult) myWebRequest.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState);
      allDone.WaitOne();
      
// Release the WebResponse resource.
      myRequestState.response.Close();
      Console.Read();
    }

    
catch(WebException e)
    
{
      Console.WriteLine(
"WebException raised!");
      Console.WriteLine(
"\n{0}",e.Message);
      Console.WriteLine(
"\n{0}",e.Status);
    }
 
    
catch(Exception e)
    
{
      Console.WriteLine(
"Exception raised!");
      Console.WriteLine(
"Source : " + e.Source);
      Console.WriteLine(
"Message : " + e.Message);
    }

  }

  
private static void RespCallback(IAsyncResult asynchronousResult)
  
{  
    
try
    
{
      
// Set the State of request to asynchronous.
      RequestState myRequestState=(RequestState) asynchronousResult.AsyncState;
      WebRequest  myWebRequest1
=myRequestState.request;
      
// End the Asynchronous response.
      myRequestState.response =  myWebRequest1.EndGetResponse(asynchronousResult);
      
// Read the response into a 'Stream' object.
      Stream responseStream = myRequestState.response.GetResponseStream();
      myRequestState.responseStream
=responseStream;
      
// Begin the reading of the contents of the HTML page and print it to the console.
      IAsyncResult asynchronousResultRead = responseStream.BeginRead(myRequestState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
    
    }

    
catch(WebException e)
    
{
      Console.WriteLine(
"WebException raised!");
      Console.WriteLine(
"\n{0}",e.Message);
      Console.WriteLine(
"\n{0}",e.Status);
    }
 
    
catch(Exception e)
    
{
      Console.WriteLine(
"Exception raised!");
      Console.WriteLine(
"Source : " + e.Source);
      Console.WriteLine(
"Message : " + e.Message);
    }

  }

  
private static  void ReadCallBack(IAsyncResult asyncResult)
  
{
    
try
    
{
      
// Result state is set to AsyncState.
      RequestState myRequestState = (RequestState)asyncResult.AsyncState;
      Stream responseStream 
= myRequestState.responseStream;
      
int read = responseStream.EndRead( asyncResult );
      
// Read the contents of the HTML page and then print to the console.
      if (read > 0)
      
{
        myRequestState.requestData.Append(Encoding.ASCII.GetString(myRequestState.bufferRead, 
0, read));
        IAsyncResult asynchronousResult 
= responseStream.BeginRead( myRequestState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
      }

      
else
      
{
        Console.WriteLine(
"\nThe HTML page Contents are:  ");
        
if(myRequestState.requestData.Length>1)
        
{
          
string sringContent;
          sringContent 
= myRequestState.requestData.ToString();
          Console.WriteLine(sringContent);
        }

        Console.WriteLine(
"\nPress 'Enter' key to continue..");
        responseStream.Close();
        allDone.Set();
      }

    }

    
catch(WebException e)
    
{
      Console.WriteLine(
"WebException raised!");
      Console.WriteLine(
"\n{0}",e.Message);
      Console.WriteLine(
"\n{0}",e.Status);
    }
 
    
catch(Exception e)
    
{
      Console.WriteLine(
"Exception raised!");
      Console.WriteLine(
"Source : {0}" , e.Source);
      Console.WriteLine(
"Message : {0}" , e.Message);
    }


  }


}


2、自动判断下载速度的问题,现在回过头来看看,因为有了微软的代码就显得这个问题比较简单了,因为我们只要去计算下载指定大小的文件的时间就可以得到;原来我是通过指定时间去计算下载文件的大小,这样就有两个问题:一是在多线程的环境中不能很好计算时间,二是这种做法需要增加很多的临时文件,比较占用空间。

3、在这个软件的开发中主要,可以说是大部分工作要使用多线程的工作,所以在线程的管理上就显得尤为重要,这一点我还没有完全掌握,经常出现线程执行不能同步的问题,这和我对线程的掌握不深有很大的关系,

经验总结:

   原来,我一直认为C#的开发语言的掌握是简单的,但是从这次的多线程管理上的缺陷,就是我深深认为掌握一门语言是需要努力去学习的。我现在只是学习其中的一点皮毛而已,尤其是C++语言我更是觉得无从下手,我只是掌握了这门语言的几个关键词而已。其中对.NET的掌握是远远不够的,而我现在想掌握的语言是C++,因为我觉得我们现在的系统是建立在C语言上的,尤其是Windows系统更是建立在MFC上的,这就要求我们很好地掌握Win32 API,而这些知识的最佳使用语言就是C++;因此要成为一位好的程序员就要求掌握C++语言。有空的时候一定要好好读读C++方面的书籍,回过头来看C#语言,他就像微软自己说的那样,这是一门快速开发语言,它能够为人们开发一些高级系统的应用软件而非底层的软件提供快速开发工具。因为C#将很多底层的操作都封装了,这就让我们远离了系统的底层,使我们的开发速度加快。
posted @ 2005-07-29 20:46  Snowolf_Studio  阅读(1106)  评论(2编辑  收藏  举报