2011-06-02 73 views
0

我發佈文件HttpWebRequest,以及頁眉和頁腳。標題(大約0.5K)和實際的文件似乎寫得很好,但對於大文件(大約15MB),頁腳(它像29個字節)似乎永遠不會寫入。HttpWebRequest流寫入永不完成

using (Stream requestStream = request.GetRequestStream()) { 
    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); 

    byte[] buffer = new byte[Math.Min(4096L, fileSize)]; 
    int bytesRead = 0; 
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { 
     requestStream.Write(buffer, 0, bytesRead); 
    } 

    // next line never completes       
    requestStream.Write(postFooterBytes, 0, postFooterBytes.Length); 

    // code below is never reached 
    Console.WriteLine("Why do I never see this message in the console?"); 
} 

有什麼想法?

ETA:嘗試最後Write()之前刷新流,上關的機會,它會有所幫助,但沒有效果。

再次編輯:新增using()澄清,我不是一個完整的白癡。另請注意,這是在的另一個using()塊的fileStream

+0

很明顯的一點,但是你確定當你不*使用HttpWebRequest時,腳註是發射的,對吧? (例如從瀏覽器或wget) – harpo 2011-06-02 21:47:25

+0

@harpo我不知道我理解。這是我排出頁腳。 – 2011-06-02 21:51:35

+0

你確定你沒有永遠循環閱讀嗎? – Daniel 2011-06-02 22:10:29

回答

2

解決:在HttpWebRequest關閉AllowWriteStreamBuffering。看起來像什麼時候開啓,無論Write()調用是否寫入最後一個字節,直到清除內部緩衝區纔會返回。所以最後的Write()最終還是在競爭,直到我跑出耐心。

因爲我最初試圖做的是確定進度,所以關閉緩衝使事情變得更加清晰。

1

一個常見的問題是忘記關閉請求流。您會看到的其中一個症狀是,請求從未制定。寫入確實完成的可能性很大,但由於您沒有關閉請求流,因此對HttpWebRequest.GetResponse()的調用似乎沒有執行。

嘗試以下,看看它是否有差別:

using (var requestStream = myRequest.GetRequestStream()) 
{ 
    // write to the request stream here 
} 
// Now try to get the response. 

另一個可能的問題是數據的大小。首先,你確定服務器可以處理15 MB的上傳嗎?其次,如果您在緩慢連接時進行此操作,15 MB可能需要一段時間才能發送。我有什麼被認爲是1.5兆位/秒的「快速」上游連接。充其量,每秒0.15兆字節。發送15兆字節將花費一分多半的時間。

另一種可能性是請求超時。您想查看HttpWebRequest.TimeoutReadWriteTimeout屬性。

+0

上面的代碼片段位於'using()'塊內部,它不是'HttpWebRequest.GetResponse()',它不會被執行,它是最後寫入之下的任何代碼 - 例如'Console.WriteLine() 。 – 2011-06-02 21:37:06

+0

@大衛:好的。看到我關於大小的說明。 – 2011-06-02 21:40:15

+0

因此,預期的行爲似乎是將所有內容都寫得很快,但是在等待「真正」寫入的時候會掛起最後一次寫入調用。因爲這種行爲在幾百K的變化中是一致的 - 文件數據循環完成,則頁腳掛起。 – 2011-06-02 21:50:48

0

當你建立你的請求時,你的內容長度也應該包含標題,確保它不只是設置爲文件長度。 您可能嘗試的另一件事是當所有事情都說完之後,在電話號碼簿上撥打.Flush()。 我不確定爲Jim提供的關閉HttpClient流的含義,它可能會起作用,它可能會使情況變得更糟。

是否使用System.Net.WebClient不能爲您提供足夠的靈活性? Theres一個不錯的UploadFile()方法可以使用。

+0

內容長度已考慮頁眉和頁腳,但謝謝。我試着在最後一個'Write()'之後添加'Flush()',但它從未到達。 – 2011-06-02 22:00:56

+0

通常在託管代碼中,行不會在沒有異常或拋出異常的情況下變得「無法訪問」。你可以嘗試在你的最後一次寫入中放置一個斷點,看看該行執行後會發生什麼?你是否曾經從你的'HttpWebRequest'對象中調用'.GetResponse()'? – Jay 2011-06-02 22:05:44