0

クライアントの要求に従って、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;
    }
}
4

1 に答える 1

0

修正しました。webclientクラスのProxyプロパティをnullに設定しましたが、修正されたようです。

于 2012-06-21T15:57:37.137 に答える