2009-10-09 39 views
0

我使用VSTS 2008 + C#+ .Net 3.5 + ASP.Net + IIS 7.0在客戶端開發Windows Forms應用程序以上載文件,而在服務器端,我使用aspx文件接收此文件。爲什麼我的WebClient上傳文件代碼掛起?

我發現我的客戶端應用程序會在點擊按鈕觸發上傳事件後掛起。任何想法什麼是錯的,以及如何解決?謝謝!

客戶端代碼,

public partial class Form1 : Form 
    { 
     private static WebClient client = new WebClient(); 
     private static ManualResetEvent uploadLock = new ManualResetEvent(false); 

     private static void Upload() 
     { 
      try 
      { 
       Uri uri = new Uri("http://localhost/Default2.aspx"); 
       String filename = @"C:\Test\1.dat"; 

       client.Headers.Add("UserAgent", "TestAgent"); 
       client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback); 
       client.UploadFileCompleted += new UploadFileCompletedEventHandler(UploadFileCompleteCallback); 
       client.UploadFileAsync(uri, "POST", filename); 
       uploadLock.WaitOne(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.StackTrace.ToString()); 
      } 
     } 

     public static void UploadFileCompleteCallback(object sender, UploadFileCompletedEventArgs e) 
     { 
      Console.WriteLine("Completed! "); 
      uploadLock.Set(); 
     } 

     private static void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e) 
     { 
      Console.WriteLine("{0} uploaded {1} of {2} bytes. {3} % complete...", 
       (string)e.UserState, 
       e.BytesSent, 
       e.TotalBytesToSend, 
       e.ProgressPercentage); 

      // Console.WriteLine (e.ProgressPercentage); 
     } 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Upload(); 
     } 
    } 

服務器端代碼:

protected void Page_Load(object sender, EventArgs e) 
    { 
     string agent = HttpContext.Current.Request.Headers["UserAgent"]; 
     using (FileStream file = new FileStream(@"C:\Test\Agent.txt", FileMode.Append, FileAccess.Write)) 
     { 
      byte[] buf = Encoding.UTF8.GetBytes(agent); 
      file.Write(buf, 0, buf.Length); 
     } 

     foreach (string f in Request.Files.AllKeys) 
     { 
      HttpPostedFile file = Request.Files[f]; 
      file.SaveAs("C:\\Test\\UploadFile.dat"); 
     } 
    } 

回答

3

你正在等待在主窗口的事件線程,因此您的GUI將被凍結。

試試這個(使用非靜態方法允許你使用Control.Invoke方法,以重繪運行Windows GUI線程和免費這個線程上回調)

public partial class Form1 : Form 
{ 
    private static WebClient client = new WebClient(); 
    private static ManualResetEvent uploadLock = new ManualResetEvent(false); 

    private void Upload() 
    { 
     try 
     { 
      Cursor=Cursors.Wait; 
      Uri uri = new Uri("http://localhost/Default2.aspx"); 
      String filename = @"C:\Test\1.dat"; 

      client.Headers.Add("UserAgent", "TestAgent"); 
      client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback); 
      client.UploadFileCompleted += new UploadFileCompletedEventHandler(UploadFileCompleteCallback); 
      client.UploadFileAsync(uri, "POST", filename);  
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.StackTrace.ToString()); 
      this.Cursor=Cursors.Default; 
      this.Enabled=false; 
     } 
    } 

    public void UploadFileCompleteCallback(object sender, UploadFileCompletedEventArgs e) 
    { 
     // this callback will be invoked by the async upload handler on a ThreadPool thread, so we cannot touch anything GUI-related. For this we have to switch to the GUI thread using control.BeginInvoke 
     if(this.InvokeRequired) 
     { 
      // so this is called in the main GUI thread 
      this.BeginInvoke(new UploadFileCompletedEventHandler(UploadFileCompleteCallback); // beginInvoke frees up the threadpool thread faster. Invoke would wait for completion of the callback before returning. 
     } 
     else 
     { 
      Cursor=Cursors.Default; 
      this.enabled=true; 
      MessageBox.Show(this,"Upload done","Done"); 
     } 
public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Upload(); 
     } 
    } 
} 

,做同樣的事情在您的進度(例如,您可以更新進度條指示符)。

乾杯, 弗洛裏安

+0

爲什麼在主窗口的事件線程在等待將圖形用戶界面將被凍結?你有更多關於這個問題的相關文件推薦閱讀嗎? – George2 2009-10-09 12:36:47

+1

Windows GUI是由消息驅動的,儘管WinForms隱藏了它。每個Windows應用程序都使用一個'Message Pumping'線程,它將消息傳遞給GUI小部件(例如鼠標移動,用戶點擊,按下按鍵等等)。您的處理程序在主窗口消息線程中運行,因此如果您等待一個事件,你會阻止windows消息泵,並且gui會出現'frozen'。你通常可以告訴它什麼時候不能重新繪製自己,例如: 請看這裏尋找一個很好的資源:http:// msdn。 microsoft.com/en-us/library/3s8xdz5c%28VS.80%29.aspx – 2009-10-09 14:00:34

+0

你在哪裏調用上傳方法? – George2 2009-10-09 14:34:39