【问题标题】:C# Background worker parameter problem?C#后台worker参数问题?
【发布时间】:2011-02-10 18:15:50
【问题描述】:

我在另一个类中调用这个 zip_threading 类。 string a = zip_threading(?,?) 但问题是当我调用此类时如何传递参数值:String [] files,bool IsOriginal。我在这个类中使用了后台工作线程,所以真正的问题是,将值传递给这个类,然后在 make_zip_file 类中完成处理时返回一个值。

public class zip_threading

{

public string[] files { get; set; } // to be recieved by the zip method as zip file names.
public int number;
public string return_path;
public bool IsOriginal { get; set; }  // to be recieved by the zip method as boolean true or fales
public static BackgroundWorker bgw1 = new BackgroundWorker(); // make a background worker object.
public void bgw1_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
{

    make_zip_file mzf1 = e.Result as make_zip_file;
    return_path = mzf1.return_path;

}
public make_zip_file bgw_DoWork(string[] files, bool IsOriginal, make_zip_file argumentest)
{

    Thread.Sleep(100);
    argumentest.return_path = argumentest.Makezipfile(files,IsOriginal);
    return argumentest;

}
public void run_async(string []files,bool IsOriginal)
{

    make_zip_file mzf2 = new make_zip_file();
   // mzf2.files = files;
    //mzf2.IsOriginal = IsOriginal;

    bgw1.DoWork += (sender, e) => e.Result = bgw_DoWork(files, IsOriginal, mzf2);
    bgw1.RunWorkerAsync();

}

public  class make_zip_file
    {

 public string return_path ;
        //public string[] files{get;set;}
       // public bool IsOriginal{get;set;}


    public string Makezipfile(string[] files, bool IsOriginal)
    {

        string[] filenames = new string[files.Length];
        if (IsOriginal)
            for (int i = 0; i < files.Length; i++)
                ***filenames[i] = HttpContext.Current.Request.PhysicalApplicationPath + files[i].Remove(0, 10).ToString();***
        else
            for (int i = 0; i < files.Length; i++)
                ***filenames[i] = HttpContext.Current.Request.PhysicalApplicationPath + files[i].Replace(HttpContext.Current.Request.UrlReferrer.ToString(), "");***
        string DirectoryName = filenames[0].Remove(filenames[0].LastIndexOf('/'));
        DirectoryName = DirectoryName.Substring(DirectoryName.LastIndexOf('/') + 1).Replace("\\", "");

        try
        {

            string newFile = HttpContext.Current.Request.PhysicalApplicationPath + "images\\Thumbnails\\zipFiles\\" + DirectoryName + ".zip";
            if (File.Exists(newFile))
                File.Delete(newFile);
            using (ZipFile zip = new ZipFile())
            {

                foreach (string file in filenames)
                {

                    string newfileName = file.Replace("\\'", "'");
                    zip.CompressionLevel = 0;
                    zip.AddFile(newfileName, "");
                }

                zip.Save(newFile);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception during processing {0}", ex);

            // No need to rethrow the exception as for our purposes its handled.
        }

        return_path = "images/Thumbnails/zipFiles/" + DirectoryName + ".zip";
return return_path;
}}

现在我在其他类中调用这个方法:像这样

String path=zipa.run_async(fileCollection, IsOriginal);

我在 make_Zip_File 中遇到错误,我将其标记为:对象引用未设置为对象的实例* 文件名 [i] = HttpContext.Current.Request.PhysicalApplicationPath + files[i].Remove(0, 10) .ToString();*

【问题讨论】:

    标签: c# backgroundworker


    【解决方案1】:

    通过将其转移到不同的线程,您在 http-context 之外运行 ,这很可能在您的 zip 操作之前很久就完成(拆除所有东西,如入站流缓冲区) -然而你正在和HttpContext.Current交谈。

    你有几个选择;脑子里乱七八糟的……

    • 在请求线程上运行它;这需要一段时间,但是嗯...
    • 在内存中缓冲您需要的所有数据,并将其传递给 zip 操作
    • 从请求线程将文件写入临时区域(不是主应用程序文件夹)中的磁盘,然后从临时区域生成一个单独的线程来处理它

    但要重申:您不能从另一个线程访问请求 - 或者至少,您不应该。

    另外,请考虑:

    • 请求开始
    • 你启动一个线程来做 zip
    • 您从原始请求返回
    • (工作线程继续运行)

    您需要考虑如何处理 zip 文件名;你不能只把它交给客户——他们不再听你的了。

    【讨论】:

    • @Marc Gravell:感谢您的建议,它们似乎很可靠,但目前我必须依赖这个,并给我一些想法或解决方案,说明为什么数据没有传递给方法?
    • @Marc Gravell:zip 文件很大,如 500 MB,这就是我在后台运行它的原因。
    • @safi - 这不会改变 http 请求/响应周期的工作方式
    • @Marc Gravell:是的,我知道,但我认为与其向用户显示繁忙的屏幕,不如在后台运行它并让用户继续他的工作。
    • @safi - 很好,但您不能继续从不再存在的请求流中读取
    【解决方案2】:

    检查文件[i]是否已初始化,因为它来自某个函数

    Makezipfile(string[] files, bool IsOriginal)
    {
    
    }
    

    我认为它没有任何价值。

    【讨论】:

    • Das:是的,这是我传递值给它的主要问题,但它给出了这个空对象引用错误,所以我认为线程有问题但无法修复:(跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    相关资源
    最近更新 更多