1

我正在使用 VSTS 2008 + C# + .Net 3.5 + ASP.Net + IIS 7.0 在客户端开发 Windows 窗体应用程序以上传文件,并在服务器端使用 aspx 文件接收此文件。

我发现单击按钮触发上传事件后,我的客户端应用程序将挂起。任何想法有什么问题以及如何解决?谢谢!

客户端代码,

  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");
        }
    }
4

1 回答 1

4

您正在主 Windows 事件线程中等待,因此您的 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();
        }
    }
}

在您的进度中做同样的事情(例如,您可以更新进度条指示器)。

干杯,弗洛里安

于 2009-10-09T10:47:17.320 回答