使程序在前进之前完成进程

本文关键字:进程 程序 | 更新日期: 2023-09-27 18:16:14

在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);
    }

使程序在前进之前完成进程

你的问题不是WebClient()特有的,而是你的应用程序是如何处理线程的

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

你可以通过实现BackgroundWorker来解决这个问题。在那个网站上,你也可以找到一个如何实现它的例子。让BackgroundWorker完成你的补丁进程,并使用BackgroundWorker. runworkerasync()方法中的事件来更新你的GUI。

如果你正在使用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);
}