2009-11-04 108 views
1

我正在做一个ftp项目,它会做多次上传,我正在做的过程是压缩文件然后加密,然后切成几块并发送给服务器,我将所有这些东西分配给thread.likewise线程将在那里为我分配的每个文件。线程问题

这是新的代码块,它只有一个功能,在这里出现了同样的错误 也请帮我找出什么是错在这里

public partial class Form1 : Form 

{ ArrayList的AscendingList =新的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); 
} 

}

+2

请修复格式。 – Yogesh 2009-11-04 05:44:46

+1

您能提供异常消息和堆栈跟踪吗? – Jehof 2009-11-11 09:14:24

+0

请使用'Path.Combine()'! – knoopx 2009-11-15 22:32:43

回答

13

这段代码乱七八糟;你应该尝试清理它。在这个过程中,你可能会发现你的bug被自己修复了。

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

基本上,它看起来像你使用的技术,你不太熟悉作出重大复杂的事情;尝试将它分成小而干净的小块,让您更精确地找出您需要的东西 - 这样您就可以更好地控制任何新技术。

清理你的第一个;然后尝试找出你剩下的任何错误 - 如果你有点幸运,你将不会有任何...

我希望这有助于!

1

为什么创建FSOUT时,你试图写在不同的线程在同一文件中,您使用FileShare.ReadWrite?这不会起作用,至少不会像这样使用GZipStream。对于您正在编写的其他文件,您指定了FileShare.None,我认为这意味着在此情况下您不会尝试从多个线程写入同一文件。

+0

hi maxc 我试图从不同的线程写入同一个文件,我chnaged gzipstream也,但我的一个线程被停止说无法访问文件。是一个竞速条件 – karthik 2009-11-04 10:30:10

2

这是有问题的:

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

的Slicer.SplitFile()调用被要求在一个不存在的文件工作。

1

无法访问该文件

这是多个线程试图访问同一文件的多线程应用普遍。

你需要做的是确保不会发生。
您不应该共享任何对象,并且每个线程都应该使用自己的文件(不能使用intersectinos)。

看着代码我可以看到切片机。 instace是共享的。
尝试将所有代码移动到Thread的Starter委托并实例化其中的所有对象。

+0

使用多线程从文件中读取很好。如果仔细设计,这种方法可以提高性能。 – 2009-11-13 14:19:01

+0

是的。我的观点是,如果执行不当,它不好。 – 2009-11-14 00:31:36

+0

这是正确的答案,这是我的代码失败 的正确原因 – karthik 2009-12-30 05:29:28