2009-11-04 105 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