C#让程序在推进之前完成流程

时间:2011-12-01 09:33:58

标签: c# process

在C#中,如何让程序一次只处理一件事?我一直在研究修补系统,我认为我的编码都是正确的,但是无法测试它,因为当需要按顺序处理时,很多功能都试图一次处理所有功能。在开始尝试处理所有内容之前,程序甚至不显示显示。因为它们都没有返回其他值,所以main函数的所有函数都设置为void。我想可能在循环中使用返回值以确保程序在继续之前首先完成该步骤,但它仍然留下程序甚至不显示的问题,直到所有内容都完成处理,它假设显示一切都在进步。有什么建议吗?

编辑:我不知道在代码中发布什么,所以即时发布所有主要功能:

    public void DSP_Load(object sender, EventArgs e)
    {
        if (v1 >= v2)
        {
            File_Progress_Title.Text = "100%";
            Update_Status.Text = "Divine Shadows is currently up to date.";
            Application.DoEvents();
            Process.Start("Divine Shadows.exe");
            Close();
        }
        else
        {
            Update_Status.Text = "Checking For Updates...";
            Application.DoEvents();

            if (!Directory.Exists(tempFilePath))
            {
                Directory.CreateDirectory(tempFilePath);
            }

            using (SqlCon = new MySqlConnection(connString))
            {
                SqlCon.Open();
                string command = "SELECT * FROM version where version > '" + v1 + "' ORDER BY version LIMIT 1";
                MySqlCommand GetLatestVersion = new MySqlCommand(command, SqlCon);

                using (MySqlDataReader DR = GetLatestVersion.ExecuteReader())
                {
                    while(DR.Read())
                    {
                        do
                        {
                            string LatestVersion = Convert.ToString(DR.GetValue(1));
                            string WebURL = Convert.ToString(DR.GetValue(2));
                            update.DownloadFileAsync(new Uri(WebURL), tempFilePath + "patch" + LatestVersion + ".zip");
                            update.DownloadProgressChanged += new DownloadProgressChangedEventHandler(download);
                            update.DownloadFileCompleted += new AsyncCompletedEventHandler(extration);
                            Application.Restart();
                        }
                        while (v1 < v2);
                        Process.Start("Divine Shadows.exe");
                        Close();
                    }
                }
            }
        }
    }

    public void download(object sender, DownloadProgressChangedEventArgs e)
    {
        if (v1 >= v2)
        {
            File_Progress_Title.Text = "100%";
            Update_Status.Text = "Divine Shadows is currently up to date.";
            Application.DoEvents();
            Process.Start("Divine Shadows.exe");
            Close();
        }
        else
        {
            Update_Status.Text = "Downloading Updates...";
            Application.DoEvents();
            File_Progress_Display.Value = e.ProgressPercentage;
            File_Progress_Title.Text = Convert.ToString(e.ProgressPercentage) + "%";
        }
    }

    public void extration(object sender, AsyncCompletedEventArgs e)
    {
        if (v1 >= v2)
        {
            File_Progress_Title.Text = "100%";
            Update_Status.Text = "Divine Shadows is currently up to date.";
            Application.DoEvents();
            Process.Start("Divine Shadows.exe");
            Close();
        }
        else
        {
            Update_Status.Text = "Installing Updates, Please Wait...";
            Application.DoEvents();
            UnzipFile(extactFile, extractLocation);
        }
    }

    public static void UnzipFile(string extactFile, string extractLocation)
    {
        try
        {
            FastZip fastZip = new FastZip();
            fastZip.CreateEmptyDirectories = false;
            fastZip.ExtractZip(extactFile, extractLocation, FastZip.Overwrite.Always, null, null, null, false); 
        }
        catch (Exception ex)
        {
            throw new Exception("Error unzipping file \"" + extactFile + "\"", ex);
        }
        File.Delete(extactFile);
    }

2 个答案:

答案 0 :(得分:0)

您的问题不是特定于WebClient(),而是关于您的应用程序如何使用线程。

通常,winforms应用程序有一个GUI线程。该线程用于执行您的方法并更新用户界面。如果您启动一个长期过程,gui线程将被锁定,直到操作完成。这就是为什么你的显示器没有显示的原因。

您可以通过实施BackgroundWorker来解决该问题。在该网站上,您还可以找到如何实现它的示例。让BackgroundWorker执行修补过程并使用BackgroundWorker.RunWorkerAsync()方法中的事件来更新GUI。

答案 1 :(得分:0)

如果您使用的是c#4或更新版本,则可以使用任务并行库以异步方式执行任务,从而在下载内容时留下您的UI响应。首先,你需要一个参考:

using System.Threading.Tasks;

还有一些代码:

public void YourMainFunction()
{
    var urls = new List<string>();
    urls.Add("http://google.com");
    urls.Add("http://yahoo.com");

    foreach(var url in urls)
    {
        Task.Factory.StartNew<DownloadResult>(() => 
             DownloadIt(url))
             .ContinueWith(WorkDone, TaskScheduler.FromCurrentSynchronizationContext());
    }
}

private class DownloadResult
{
    public string Url {get; set;}
    public string Result {get; set;}
}

private DownloadResult DownloadIt(string url)
{
    var downloadResult = new DownloadResult{ Url = url };
    var client = new WebClient();
    downloadResult.Result = client.DownloadString(url);
    return downloadResult;
}

private void WorkDone(Task<DownloadResult> task)
{
    if(task.IsFaulted)
    {
        //An exception was thrown 
        MessageBox.Show(task.Exception.ToString());
        return;
    }

    //Everything went well
    var downloadResult = task.Result;
    //Here you can update your UI to reflect progress.
    MessageBox.Show(downloadResult.Result);

}