下载应用程序时,它会在进程中随机跳转文件

时间:2016-08-26 19:57:04

标签: c# .net wpf multithreading


我正在开发一个c#patcher,它的作用是比较客户端和服务器的文件,如果存在一些不一致的地方,它会自动下载它们。
它是一个WPF应用程序,用于在更新进度条时处理多个异步下载,我使用了net 4.5 async / await。 它工作得很好,但是现在我需要在windows xp上运行相同的应用程序,我决定使用BackgroundWorker重构所有代码,后者也是在net 4中是不可思议的,最后一个由xp支持。
< BR />

问题是文件(特定的一个),开头没有下载。
当有3个不同的文件下载时,如果有问题的文件是例如第二个,在第一个之后,下载开始了,但它几乎立即跳到第三个,第二个以0KB的大小 如果有问题的文件是第一个或最后一个,结果是相同的。这就像程序不喜欢它 经过一些没有效果的改变之后,我决定回滚所有我做过的事情,回到初始代码 那么现在我没有问题,所有文件都正确下载,但有趣的是,如果我将同一个可执行文件提供给另一个人,他仍然有同样的问题。
我不知道怎么可能,这个文件和其他文件完全一样。

该软件的其他一些信息:
在开始时,程序检查所有文件是否相同,将每个文件的MD5哈希值与一个文件进行比较,该文件包含更新文件的所有MD5哈希值(使用php脚本生成之前)。
现在如果有一些文件要下载,程序会在窗口中注入文件,最后一个文件将它们注入HTTPDownloader(如果有的话)。
HTTPDownload使用for循环开始下载所有文件,为client.isBusy发出错误信息,以确保不进行并行I / O操作。
有一个DownloadListener,它可以监听所有WebClient事件和一些习俗。它使用Dispatcher更新进度条,状态文本块等,因为事件将在另一个线程中触发(通过HTTPDownloader)。
事后发生的事情对于这个具体问题并不重要。

这些是感兴趣的文件:

window.xaml.cs

public void repairButtonClick(object sender, RoutedEventArgs e)
{
    repairButton.IsEnabled = false;
    startButton.IsEnabled = false;
    currentFile.Text = "Hashing files...";
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += (object s, DoWorkEventArgs es) =>
    {
        scanner.search();
    };
    bw.RunWorkerCompleted += (object s, RunWorkerCompletedEventArgs ev) =>
     {
         toUpdateFiles = scanner.getToUpdateFiles();
         if (toUpdateFiles != null && toUpdateFiles.Count > 0)
         {
             _startDownload();
         }
         else
         {
             currentFile.Text = "";
             System.Windows.MessageBox.Show(this, "Your client is OK!", "Patcher");
             startButton.IsEnabled = true;

         }
     };
    bw.RunWorkerAsync();

}

这是一个点击事件处理程序,没有问题,但它会调用_startDownload方法。

window.xaml.cs

void _startDownload()
{
    HTTPDownloader downloader = new HTTPDownloader(toUpdateFiles, client,"source/");
    DownloadListener listener = new DownloadListener(this, downloader);
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += (object s, DoWorkEventArgs e) =>
    {

        downloader.startDownload();
    };
    bw.RunWorkerAsync();
}

HTTPDownloaderWebClient的包装 DownloadListener是一个倾听所有WebClient下载事件(以及一些习俗)的听众 BackgroundWorker运行HTTPDownloader.startDownload()方法

HTTPDownloader.cs

public void startDownload()
{
    if (Progress != null) client.DownloadProgressChanged += Progress;
    if (Completed != null) client.DownloadFileCompleted += Completed;

    if (client.BaseAddress.Length == 0)
    {
        throw new Exception("BaseAddress missing in the WebClient Object");
    }
    for (int i = 0; i < files.Count; i++)
    {
        PatchFile file = files[i];
        setCurrentIndex(i + 1);
        OnNewFile(file);
        setCurrentFile(file);
        string path = Path.Combine(file.getBasePath(), file.getName());
        string downloadPath = basePath + path;

        if (file.basePath != String.Empty) Directory.CreateDirectory(Path.GetDirectoryName(path));
        client.DownloadFileAsync(new Uri(new Uri(client.BaseAddress), downloadPath), path);
        while (client.IsBusy)
        {
        }
        OnAfterNewFile(file);


    }
    OnAllFileDownloaded();
}

我们在这里,这是最重要的方法 它会下载所有文件,引发一些事件 (一个offtopic问题:while(client.isBusy)是一个好的方法,等到下载完成启动另一个?(不提高I / O WebClient异常))

请帮助我,我是如此倾斜。在我和其他计算机上以相反的方式运行相同的可执行文件是没有意义的 也许线程以不同的方式管理,我不知道,我对应用程序编程很新(所以如果我的window.xaml.cs有一些业务逻辑并且我使用一种不同的方式处理ui,请不要责怪我(DownloadListener),当我看到MVVC模式时已经很晚了)。

谢谢

1 个答案:

答案 0 :(得分:0)

解决了问题,是托管文件存在问题