我写了个winform的自动更新,但是客户端更新速度太慢了,用户有意见,请问下大家有没有什么好办法?
客户端代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;namespace Update
{
    public partial class StartRun : Form
    {
        SerUpdate.Calculate cs = new SerUpdate.Calculate();
        int RersionDif = 0;        public StartRun()
        {
            InitializeComponent();
            string nVer = cs.GetVer();
            //nVer = "1.0.1.3";
            RersionDif = Application.ProductVersion.CompareTo(nVer);
            if (RersionDif < 0)
            { update(); }
        }        private void StartRun_Load(object sender, EventArgs e)
        {
            if (RersionDif < 0)
            {
                System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses();
                foreach (System.Diagnostics.Process p in ps)
                {
                    if (p.ProcessName.ToLower() == "Hotel")
                    {
                        p.Kill();
                        break;
                    }
                }
                XmlDocument doc = new XmlDocument();
                doc.Load(Application.StartupPath + @"\update.xml");
                XmlElement root = doc.DocumentElement;
                XmlNode updateNode = root.SelectSingleNode("filelist");
                string path = updateNode.Attributes["sourcepath"].Value;
                int count = int.Parse(updateNode.Attributes["count"].Value);
                for (int i = 0; i < count; i++)
                {
                    XmlNode itemNode = updateNode.ChildNodes[i];
                    string fileName = itemNode.Attributes["name"].Value;
                    FileInfo fi = new FileInfo(fileName);
                    if (fi.Exists)
                    { fi.Delete(); }
                    CreateFolder(fileName);                    this.statusBarPanel.Text = "正在更新: " + fileName + " (" + itemNode.Attributes["size"].Value + ")...";
                    FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.Write);                    fs.Write(System.Convert.FromBase64String(itemNode.SelectSingleNode("value").InnerText),
    0, int.Parse(itemNode.Attributes["size"].Value));
                    fs.Close();
                }
                statusBarPanel.Text = "更新完成";
                File.Delete(Application.StartupPath + @"\update.xml");
            }
            statusBarPanel.Text = "正在重新启动应用程序...";
            System.Diagnostics.Process.Start("Hotel.exe");
            Close();
            Application.Exit();
        }        void update()
        {
            this.statusBarPanel.Text = "正在下载...";
            System.Xml.XmlDocument doc = cs.GetUpdateData();
            doc.Save(Application.StartupPath + @"\update.xml");
            //System.Diagnostics.Process.Start(Application.StartupPath + @"\UpdateDemo.exe");
            //Close();
            //Application.Exit();
        }        void CreateFolder(string fileroad)
        {
            string[] folds = fileroad.Split(new Char[] { '\\' });
            if (folds.Length > 0)
            {
                string curfiles = "";
                for (int i = 0; i < folds.Length - 1; i++)
                {
                    if (i == 0)
                    { curfiles = folds[i]; }
                    else
                    { curfiles += "\\" + folds[i]; }
                    DirectoryInfo TheFolder = new DirectoryInfo(curfiles);
                    if (!TheFolder.Exists)
                    {
                        Directory.CreateDirectory(curfiles);
                    }
                }
            }
        }    }
}
服务端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.IO;namespace SiteDemo
{
    /// <summary>
    /// Calculate 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]
    public class Calculate : System.Web.Services.WebService
    {        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }        [WebMethod(Description = "取得更新版本")]
        public string GetVer()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(Server.MapPath("update.xml"));
            XmlElement root = doc.DocumentElement;
            return root.SelectSingleNode("version").InnerText;
        }        [WebMethod(Description = "在线更新软件")]
        //[SoapHeader("sHeader")]
        public System.Xml.XmlDocument GetUpdateData()
        {
            //验证用户是否登陆
            //if (sHeader == null) return null;
            //if (!DataProvider.GetInstance.CheckLogin(sHeader.Username, sHeader.Password)) return null;
            //取得更新的xml模板内容
            XmlDocument doc = new XmlDocument();
            doc.Load(Server.MapPath("update.xml"));
            XmlElement root = doc.DocumentElement;
            //看看有几个文件需要更新
            XmlNode updateNode = root.SelectSingleNode("filelist");
            string path = updateNode.Attributes["sourcepath"].Value;
            int count = int.Parse(updateNode.Attributes["count"].Value);
            //将xml中的value用实际内容替换
            for (int i = 0; i < count; i++)
            {
                XmlNode itemNode = updateNode.ChildNodes[i];
                string fileName = path + itemNode.Attributes["name"].Value;
                FileStream fs = File.OpenRead(Server.MapPath(fileName));
                itemNode.Attributes["size"].Value = fs.Length.ToString();
                BinaryReader br = new BinaryReader(fs);
                //这里是文件的实际内容,使用了Base64String编码
                itemNode.SelectSingleNode("value").InnerText =
                Convert.ToBase64String(br.ReadBytes((int)fs.Length), 0, (int)fs.Length);
                br.Close();
                fs.Close();
            }
            return doc;
        }    }
}

解决方案 »

  1.   

    看看是什么原因导致客户端太慢,是网络传输慢呢,还是客户端某个地方耗时呢,还是代码有问题呢,还是webservice配置有问题呢,还是 自己调试下看看。
      

  2.   

    这里是文件的实际内容,使用了Base64String编码没有用二进制也就罢了
    如果文件比较大或者想加快下载速度,那就应该压缩
    Base64String会增加传输的数据量(编码后的数据大于原始文件)
      

  3.   

    用VS自带的直接发布不行吗?干嘛要自己写一个?
    如果有客户端的数据库在更新的,多写-个项目更新数据库结构用的(把生成的exe包含在发布项目里面,客户端了现有p这个exe在根目录就运行一下,然后删除就行了)。
      

  4.   

    你是说clickonce,那个好像不太好用,有那位有没有个好点的例子啊,我的那个是可以的,但是就是更新速度太慢
      

  5.   

    可以参考我的程序看看:http://download.csdn.net/detail/ybhzf/4885096。
      

  6.   

    这个可以有,想chrome浏览器一样,在更新的时候,完全不影响你的使用,完成以后,重新启动就ok了
      

  7.   

    唉。仅就你的这个策略而言说几句。web service不是用来下载文件的,它是针对数据解析的。如果你的数据结构很简单,或者自己解析,就不要使用web service。为什么要下载所有文件?你应该仅仅下载与客户端不一样的文件。例如客户端在查询服务器上的版本时,可以给出客户端的所有文件的md5签名值,服务器于是就可以返回给客户端信息“先删除哪些文件,然后下载哪些文件”。下载应该是并发多线程的,例如5个线程(或者100个线程)来下载文件。不管你说线程太多了有什么坏处,在此也会强过单线程下载。
      

  8.   

    比如说我们下载一个文件,使用new WebClient().DownloadFile(url, file);这就行了。获取文件何必用什么webservice?还base64编码?
      

  9.   

    慢的原因很清楚啊,你把所有文件一次性传输(并且还是base64传输)建议分开传输(5线程同时),并且直接二进制传输