没有搞异常,假设所有操作都是正确的从数据库某一个字段提示的url下载相应的文件
WebClient好像很卡
using System;
using System.Configuration;
using System.IO;
using System.Data.OleDb;
using System.Net;
using System.Threading;
namespace FileDownload
{
    class Program
    {
        static OleDbConnection conn =
            new OleDbConnection(ConfigurationManager.ConnectionStrings["database"].ConnectionString);
        static String idfield = ConfigurationManager.AppSettings["id"];
        static String tablename= ConfigurationManager.AppSettings["tablename"];
        static String filefield = ConfigurationManager.AppSettings["filefield"];
        static String newfilefield = ConfigurationManager.AppSettings["newfilefield"];
        static String sql1 ="select {0},{1} from {2}";
        static String sql2 = "update {0} set {1} = '{2}' where [id] = {3}";
        static OleDbCommand qcmd = null;
        static OleDbCommand insertcmd = null;
        static String savebase  = ConfigurationManager.AppSettings["savebase"];
        static String relative = ConfigurationManager.AppSettings["relative"];
        static bool userelative = true;
        static OleDbDataReader reader;
        static int threadquantity  =int.Parse(ConfigurationManager.AppSettings["threadq"]);
        static Thread[] workers = new Thread[threadquantity];
        static ManualResetEvent[] events = new ManualResetEvent[threadquantity];
        static Random random = new Random();
        static StreamWriter excpwrt = 
            new StreamWriter(new FileStream("exception.txt", FileMode.OpenOrCreate | FileMode.Append));        static void Main(string[] args)
        {
            String querysql =  String.Format(sql1,idfield, filefield , tablename);
            insertcmd = new OleDbCommand();
            insertcmd.Connection = conn;
            insertcmd.CommandType = System.Data.CommandType.Text;
            conn.Open();
            qcmd = new OleDbCommand(querysql, conn);
            reader = qcmd.ExecuteReader();            if (String.IsNullOrEmpty(savebase)) {
                savebase = String.Empty;
            }            if(String.IsNullOrEmpty(relative)){
                userelative = false;            }            Console.WriteLine("开始下载...");            for (int i = 0; i < threadquantity; i++) {
                workers[i] = new Thread(Worker);
                events[i] = new ManualResetEvent(false);
                workers[i].Start(events[i]);
                Thread.Sleep(10);
            }            WaitHandle.WaitAll(events);
            Console.WriteLine("下载完成...");
            if(reader!=null)
                reader.Close();
            if (conn != null)
                conn.Close();
            if (qcmd != null)
                qcmd.Dispose();
            if (insertcmd != null)
                insertcmd.Dispose();
            excpwrt.Close();
        }        static String GetFileExt(String url) {
            int di = url.LastIndexOf(".");
            String ext = url.Substring(di);
            return ext;
        }        static void Worker(object parm) {
            ManualResetEvent e = parm as ManualResetEvent;
            bool flag = true;
            String id;
            while (flag)
            {
                lock (reader) {
                    flag =  reader.Read();
                    id =  reader[idfield].ToString();
                    if (!flag)
                        break;
                }
                WebClient client = new WebClient();
                try
                {
                    String url = reader[filefield].ToString();
                    String ext = GetFileExt(url);
                    String fn = DateTime.Now.ToString("yyyyMMddhhmmssfff") + random.Next(100).ToString() + ext;
                    String newfilename = savebase + fn;
                    Console.WriteLine("开始尝试下载文件");                    client.DownloadFile(url, newfilename);
                    if (userelative)
                        newfilename = relative + fn;                    String insertsql =
                        String.Format(sql2, tablename, newfilefield, newfilename, id);                    insertcmd.CommandText = insertsql;
                    insertcmd.ExecuteNonQuery();                    Console.WriteLine("文件已下载...");                }
                catch (Exception ex)
                {
                    lock (excpwrt) {
                        excpwrt.WriteLine(ex.ToString());
                        excpwrt.WriteLine(DateTime.Now.ToString());
                        excpwrt.WriteLine();
        
                        excpwrt.Flush();
                    }
                }
                
            }
            e.Set();
        }
        
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="database" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\Administrator\桌面\SpiderResult(1).mdb"/>
  </connectionStrings>
  <appSettings>
    <add key="tablename" value= "content" />
    <add key="id" value="id"/>
    <add key="filefield" value="出处" />
    <add key="newfilefield" value="作者" />
    <add key="savebase" value="d:\test\" />
    <add key="relative" value="\test\" />
    <add key="threadq" value="10" />
  </appSettings>
</configuration>

解决方案 »

  1.   

    改用异步: WebClient.DownloadFileSync
      

  2.   

      WaitHandle.WaitAll(events); 跟同步没啥区别 其实 Thead.Start 之后,就 Console.Read() 等子线程打结果吧。
      

  3.   

    网速好的时候很块,如果网咯不好的话就会卡在哪里,不会下载东西。。
    还有这个
    String fn = DateTime.Now.ToString("yyyyMMddhhmmssfff") + random.Next(100).ToString() + ext;
    String newfilename = savebase + fn;
    //..                     
    client.DownloadFile(url, newfilename);
    好像有很小的概率文件重名。然后。就报资源被另一个进程占用的异常求解决。。