문제

내 양식 생성자에는 초기화 구성 요소 뒤에 다음 코드가 있습니다.

using (WebClient client = new WebClient())
{
    client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
    client.DownloadDataAsync("http://example.com/version.txt");
}

양식을 시작하면 client_DownloadDataCompleted가 발생할 때까지 UI가 나타나지 않습니다.client_DownloadDataCompleted 메서드는 비어 있으므로 문제가 없습니다.

내가 뭘 잘못하고 있는 걸까요?UI를 정지하지 않고 어떻게 이 작업을 수행할 수 있나요?

시간 내 줘서 고마워.
친애하는.

전체 코드:

Program.cs

using System;
using System.Windows.Forms;

namespace Lala
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.cs

using System;
using System.Net;
using System.Windows.Forms;

namespace Lala
{
    public partial class Form1 : Form
    {
        WebClient client = new WebClient();

        public Form1()
        {
            client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
            client.DownloadDataAsync(new Uri("http://www.google.com"));
            InitializeComponent();
        }

        void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            textBox1.Text += "A";
        }
    }

    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 41);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(468, 213);
            this.textBox1.TabIndex = 1;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(492, 266);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox textBox1;
    }
}
도움이 되었습니까?

해결책

이제 전체 코드가 있으므로 문제가 전혀 보이지 않는다고 말할 수 있습니다. 어쨌든 설명과는 다릅니다.

DownloadDataAsync 호출 직전과 직후, 완료된 처리기가 실행되는 시기를 나타내는 약간의 로깅이 있습니다.3G로 대용량 파일을 다운로드하면 ~이다 "이전"과 "이후" 사이에 일시 중지가 있지만 파일 다운로드가 완료되기 전에 UI가 표시됩니다.

나는 의심이 든다. 연결하다 다운로드는 동기식으로 수행되지만 실제 다운로드는 비동기식입니다.물론 그것은 여전히 ​​불행한 일입니다. 아마도 그 모든 것을 다른 스레드에 넣는 것이 좋은 방법일 것입니다. 그러나 제가 옳다면 적어도 알 가치는 있습니다.

다른 팁

동일한 문제가 발생하여 해결책을 찾았습니다. 여기에 매우 복잡한 토론 :http://social.msdn.microsoft.com/forums/en-us/a00dba00-5432-450b-9904-9d343c11888d/webclient-downloadstringasync-freeze-my-ui?forum=ncl

요컨대, 문제는 웹 클라이언트가 프록시 서버를 검색하고 앱을 걸고 있다는 것입니다. 다음 솔루션이 도움이됩니다.

WebClient webClient = new WebClient();
webClient.Proxy = null;
... Do whatever else ...

다른 스레드에서 다운로드를 실행하려고합니다. 이것 출발점으로.

비동기 호출에 여전히 사용하는 동안 웹 클라이언트를 처분하는 것과 관련이 있다고 생각합니다.

사용 명령문을 제거하고 대신 이벤트 핸들러에서 호출을 요청하십시오. (또는 단지 테스트를 위해서는 전혀 처리 할까 걱정하지 마십시오.

게시 할 수 있다면 a 짧지 만 완전한 프로그램 문제를 보여 주면 정말 편리합니다.

다른 사람들이 언급 한 비동기 호출을 여전히 실행하는 것을 처분 할뿐만 아니라 양식의 생성자에서 이와 같은 헤비급 작업을 수행하는 것을 강력히 권장합니다.

대신 Onload Override에서 수행하십시오. 여기서 VS Forms Designer를 사용하여 여러 수준의 지옥을 피하는 데 도움이되는 DesignMode 속성을 확인할 수 있습니다.

배치되지 않은 : 많은 사람들이 나처럼 사용 블록에 대해 생각하는 것처럼 ~ 아니다 관련된.

사용 블록을 제거 할 수 있습니까? WebClient 인스턴스를 처리하기를 기다리고 있다고 생각합니다.

비 UI 스레드에서 다운로드 dataasync vs. downloadData :

DownloadDataAsync는 요청이 작성되고 서버가 응답 한 후 DownloadDatacempletedEvent를 처리 할 때까지 실제로 스레드를 묶지 않기 때문에 좋습니다.

Jon Skeet이 올바른 길을 가고 있다고 생각합니다. 비동기 HTTP 요청이 대기되고 다운로드 dataasync 호출이 반환되기 전에 DNS 해상도가 동기식으로 완료되어야한다는 것을 읽었습니다.

DNS 해상도가 느릴 수 있습니까?

방금 VS2010, .NET 4에 따라 WPF 프로젝트에서 동일한 것을 테스트했습니다.

WebClient.DownloadDatACEMPleted 등을 사용하여 완료된 백분율을 표시하기 위해 진행률 표시 줄이있는 파일을 다운로드하고 있습니다.

그리고 놀랍게도, 나는 @dan이 언급 한 것과 같은 것을 발견합니다. 디버거 내에서 스레드를 재미있는 방식으로 차단합니다. 디버그에서 내 진행중기 미터는 1%로 업데이트 된 다음 잠시 동안 아무것도하지 않고 갑자기 100%로 다시 업데이트됩니다. (Debug.writeln 문장 전체에 부드럽게 인쇄). 이 두 번 사이에 UI가 얼어 붙었습니다.

그러나 디버거 밖에서 진행률 막대는 0%에서 100%로 원활하게 움직이며 UI는 결코 얼지 않습니다. 당신이 기대하는 것입니다.

이 시도:

client.Proxy = GlobalProxySelection.GetEmptyProxy();

그것은 나에게 조금 이상해 보인다.

webclient의 회원 Ref를 생성자에서 파괴하지 않도록하려면 Client.Dispose ()에서 차단 될 수 있습니다.

using() 문은 다운로드하는 동안 WebClient의 Dispose()를 호출하려고 합니다.Dispose 메서드는 계속하기 전에 다운로드가 완료될 때까지 기다립니다.

using() 문을 사용하지 말고 DownloadDataCompleted 이벤트에서 WebClient를 삭제해 보세요.

코드를 잘 실행할 수 있습니다. 양식이 나타나고 양식이 나타나면 다운로드가 완료됩니다.

당신이 언급했듯이 동결이 없습니다.

나는 그것이 당신이 그것을 실행하는 환경과 관련이 있다고 생각합니다.

.NET/Visual Studio의 어떤 버전에 있습니까?

나는 당신의 코드를 시도했고 그것은 잘 작동합니다.

메인 (Args []) 메소드와 A와 B의 값을 실행할 때 게시 할 수 있습니까?

    int a, b;
    ThreadPool.GetMaxThreads(out a, out b);

.NET 3.5와 VS2008에서 시도했습니다. 나는 손실에 있지만, 그것이 당신의 컴퓨터의 설정과 관련이 있다고 확신합니다. 코드가 아닙니다. 이런 것들을 확인하십시오.

  • 스레드 풀 (위)을 확인하십시오. 나는 a = 250 b = 1000을 얻는다
  • 모든 타사 플러그인을 비활성화하십시오
  • 로드 대 "깨끗함"(재부팅 된 사람)
  • 가능한 한 많은 프로그램/서비스를 닫습니다
  • IE 구성을 확인하십시오. 클래스는 IE 코드/설정을 사용한다고 생각합니다
  • 방화벽? 바이러스 백신?
  • 다른 컴퓨터에서 시도하십시오

음 .... 나는 단지 궁금합니다

방화벽이 있습니까?

어느 기계의 방화벽?

아마도 ZoneAlarm?

내 경험상 프로젝트 디버깅을 실행할 때 (Visual Studio 내에서 실행), 서버에 처음 액세스 할 때 스레드가 차단됩니다.

컴파일 된 EXE를 실행할 때는 차단을 인식 할 수 없습니다.

이 문제는 VS2015에서도 여전히 진행 중입니다. 나는 마침내 이것을 알아 냈습니다. 사람들이 사용하는 코드에 아무런 문제가 없습니다. 문제는 실제로 레이블 컨트롤에 데이터를 얼마나 빨리 작성하는지입니다. 이것이 프로세스를 끊고 UI가 동결되는 원인입니다. 진행중인 핸들러의 텍스트 상자로 참조하는 레이블을 교체 해보십시오. 이것은 저를 위해 UI의 모든 지연을 해결했습니다. 저는 코드가 다른 사람들이 아닌 때때로 작동하는 이유를 알아 내기 위해 몇 시간을 보냈을 때 다른 사람들이 도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top