线程问题

时间:2009-11-04 05:41:51

标签: c# multithreading ftp c#-2.0

我正在做ftp中的一个项目,它将进行多次上传,我正在做的过程是压缩文件然后加密然后切成几块并将其发送到服务器我将所有这些东西分配给一个线程。我指定的每个文件都有一个线程。

这是新的代码片段,它只有一个功能,此处出现相同的错误 也请帮我看看这里错了什么

public partial class Form1 : Form 

{     ArrayList AscendingList = new ArrayList();     ListViewItem Litem = null;     线程MyThread = null;     ThreadStart Starter = null;

public Form1() 
{ 
    InitializeComponent(); 
} 

private void btn_split_Click(object sender, EventArgs e) 
{ 
    foreach (ListViewItem litem in listView1.Items) 
    { 
        Starter = delegate { SplitFile(litem.Text,litem.SubItems[1].Text,int.Parse(litem.SubItems[2].Text)); }; 
        MyThread = new Thread(Starter); 
        MyThread.IsBackground = true; 
        MyThread.Start(); 
    } 
} 
public void SplitFile(string inputFile, string outputPrefix, int chunkSize) 
{ 
    int pointr = 0; 
    byte[] buffer = new byte[chunkSize]; 

    using (FileStream fs = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.None)) 
    { 
        int index = 0; 
        pointr = fs.Read(buffer, 0, buffer.Length); 
        while (pointr != 0) 
        { 
            using (FileStream fso = new FileStream(outputPrefix + "\\" + index + ".log", FileMode.Create)) 
            { 
                AscendingList.Add(fso.Name); 
                fso.Write(buffer, 0, pointr); 
                pointr = fs.Read(buffer, 0, buffer.Length); 
            } 
            index++; 
        } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Litem = new ListViewItem(); 
    Litem.Text = "E:\\butterfly.mpg"; 
    Litem.SubItems.Add("H:\\karthik"); 
    Litem.SubItems.Add("102400"); 
    listView1.Items.Add(Litem); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    Litem = new ListViewItem(); 
    Litem.Text = "E:\\karthik.mpeg"; 
    Litem.SubItems.Add("H:\\karthik\\karthik"); 
    Litem.SubItems.Add("102400"); 
    listView1.Items.Add(Litem); 
} 

}

4 个答案:

答案 0 :(得分:13)

这段代码很乱;你可能应该尝试清理它。在此过程中,您可能会发现自己的错误已得到修复。

  • 你有几个空的catch子句,这是一个很大的红旗(注释掉使用块是一个更好的主意)。这些应该所有被删除;这些都不是一个好主意。
  • 你有一个线程.Sleep语句可能是超级的 - 如果不是,那就是线程错误的迹象。
  • 您应该将基本功能拆分为辅助方法。这样可以提高代码的可读性,从而提高代码的可调试性 - 并以私有帮助程序方法的名称自动提供一些文档。例如,您的读取A写入B代码可能是一种方法 - 您在SplitFileDecompress中都复制了此功能。
  • 你有一堆错误的.Read(语句假设读取实际读取完整的缓冲区 - 它没有,它等待至少1个字节可用并且只返回立即可用的,或者返回0流完成了。您应该从不忽略.Read(方法返回的字节数。如果您将({1}}和SplitFile中基于时间的(更好)代码拆分为辅助方法,您也可以在其他地方使用它。 写入网络或物理驱动器时很可能会出现问题
  • 可以编写多个使用块而无需额外的花括号来提高可读性。如果这样做,VS.NET将不会为每个using()子句添加缩进级别,但只为所有子句添加一个缩进级别。
  • 我不太清楚,但看起来你正在使用一堆中间文件。一种更干净(可能更快)的方法是简单地处理流并且有一个恰好提供文件流的包装器。
  • Decompress之前您无需.Flush()
  • 每个 .Close()放在一个使用块中是个好习惯。即使像IDisposableMemoryStream之类的东西 - 它也可能并不重要,但无论如何我都会看到你CryptoStream - 所以你没有保存任何代码,而且你'重新违反代码合同,你可能不知道他们的实现,所以你依赖于未指明的行为;这不值得。
  • .Close()相当于.Substring(....).ToString()

基本上,看起来你正在使用你并不熟悉的技术制作一件大事。尝试将它分成小巧,干净的位,让您更准确地指出您需要的东西 - 这样您就可以更好地保持对任何新技术的控制。

清理你拥有的东西;然后尝试查明你剩下的任何错误 - 如果你有点幸运,你将不会有任何错误......

我希望这有帮助!

答案 1 :(得分:2)

这是有问题的:

string EncryptedFile = "";
Slicer.SplitFile(EncryptedFile, lt.SubItems[3].Text, 10240);

要求Slicer.SplitFile()调用处理不存在的文件。

答案 2 :(得分:1)

为什么在创建fsout时使用FileShare.ReadWrite,您是否尝试从不同的线程写入同一文件?这不会起作用,至少不会像那样使用GZipStream。使用您正在编写的另一个文件,您已经指定了FileShare.None,我认为这意味着在这种情况下您不会尝试从多个线程写入同一文件。

答案 3 :(得分:1)

  

无法访问该文件

这对于多线程尝试访问同一文件的多线程应用程序很常见。

您需要做的是确保不会发生这种情况 您不应该共享任何对象,并且每个线程应该使用自己的文件(没有相交)。

查看代码,我可以看到 Slicer。 instace是共享的 尝试将所有代码移动到Thread的 Starter 委托中,并实例化那里的所有对象。