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 に答える