Ui线程被阻止但仅在第一次调用Webclient异步方法时被阻止

时间:2012-06-21 14:20:43

标签: c# webclient

根据客户的请求,我编写了一个继承自webclient的通信类。他们希望能够“将自定义窗体表单作为进度条传递”,而不是创建一个实现3个属性的界面。无论如何我遇到的问题是应用程序启动,我点击开始按钮,所以说,第一次我这样做,ui线程被冻结,几秒钟后解冻,进度条和数据开始下降。

在初始冻结之后,任何后续按下的开始按钮都能完美地工作并且不会阻止任何想法吗?

以下是表格1的相关代码

private void btnSubmit_Click(object sender, EventArgs e)
    {
        txtResponse.Text = "";
        progressForm = new ProgressFormTest();
        myCommunication = new CommunicationClient(progressForm);
        myCommunication.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_RequestComplete);
        // myCommunication.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
        myCommunication.Timeout += new EventHandler(wc_TimeOut);
        myCommunication.Cancelled += new EventHandler(myCommunication_Cancelled);


        progressForm.Show();
        myCommunication.TimeoutValue = (int)numConnectionTimeout.Value * 1000;

        myCommunication.DownloadStringAsync(new Uri(txtUrl.Text));


    }

这是通讯类

    public class CommunicationClient:WebClient
    {
    private int step = 1000;
    private long bytesReceived;
    private long bytesSent;
    private Status status;
    private System.Timers.Timer _timer;
    private IProgress myProgressForm;

    /// <summary>
    /// Sets the timeout value in milliseconds
    /// </summary>
    public int TimeoutValue { get; set; }
    public int TimeElapsed { get; set; }
    public long BytesReceived
    {
        get
        {
            return bytesReceived;
        }
    }
    public long BytesSent
    {
        get
        {
            return bytesSent;
        }
    }

    public event EventHandler Timeout;
    public event EventHandler Cancelled;

    public CommunicationClient(IProgress progressForm)
    {
        myProgressForm = progressForm;
        _timer = new System.Timers.Timer(step);
        _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    }





    protected override void OnDownloadStringCompleted(DownloadStringCompletedEventArgs e)
    {
        _timer.Stop();
        if (status == Status.Completed)
        {
            myProgressForm.PercentComplete = 100;
            base.OnDownloadStringCompleted(e);
        }
    }





    protected override void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e)
    {
        bytesReceived = e.BytesReceived;
        myProgressForm.BytesReceived = bytesReceived;
        if (e.TotalBytesToReceive == -1)
            myProgressForm.PercentComplete = calculateFakePercentage();
        else
            myProgressForm.PercentComplete = e.ProgressPercentage;
        base.OnDownloadProgressChanged(e);
    }

    protected virtual void OnTimeout(EventArgs e)
    {
        if (Timeout != null)
        {
            CancelAsync();
            this.Dispose();
            Timeout(this, e);
        }
    }

    protected virtual void OnCancelled(EventArgs e)
    {
        if (Cancelled != null)
        {
            this.Dispose();
            Cancelled(this, e);
        }
    }

    /// <summary>
    /// Cancels a pending asynchronous operation and raises the Cancelled Event
    /// </summary>
    /// <param name="Event">Set to true to raise the event</param>
    public void  CancelAsync(bool Event)
    {
        CancelAsync();
        if (Event)
        {
            status = Status.Cancelled;
            OnCancelled(new EventArgs());
        }
    }

    private void initialize()
    {
        status = Status.Completed;
        TimeElapsed = 0;
        _timer.Start();
    }



    new public void DownloadStringAsync(Uri url)
    {
        initialize();
        base.DownloadStringAsync(url);
    }

    private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        TimeElapsed += step;

        if (TimeElapsed >= TimeoutValue)
        {
            _timer.Stop();
            status = Status.Timeout;
            OnTimeout(e);
        }
    }    

    //used when the website in question doesnt provide the content length
    private int calculateFakePercentage()
    {
        return  (int)bytesReceived * 100 / 60000 ;
    }        
}

这是简单的接口IProgressForm

public interface IProgress
{
    int PercentComplete
    {
        get;
        set;
    }
    long BytesReceived
    {
        get;
        set;
    }
    long BytesSent
    {
        get;
        set;
    }
}

1 个答案:

答案 0 :(得分:0)

修正了它,我将webclient类的Proxy属性设置为null,这似乎解决了它