1

次のコードが少しあります:

フォーム上:

    List<WebRequestUri> lwebrequest = new List<WebRequestUri>();

    public Form1()
    {
        InitializeComponent();
    }

    private void Start_Click(object sender, EventArgs e)
    {
        Thread thread = new Thread(new ParameterizedThreadStart((object context) =>
            {
                DoWork();
            }));
        thread.IsBackground = true;
        thread.Start();            
    }

    void DoWork()
    {
        lwebrequest = new List<WebRequestUri>();
        for (int i = 0; i < 100; i++)
        {
            WebRequestUri wp = new WebRequestUri();
            wp.Start();
            lwebrequest.Add(wp);
        }
    }

    private void Stop_Click(object sender, EventArgs e)
    {                  
        for (int i = 0; i < lwebrequest.Count; i++)
        {               
            lwebrequest[i].Abort();
        }
    }

ワーカー クラス:

class WebRequestUri
{
    Thread thread = null;
    WebRequest webRequest = null;
    WebResponse webResponse = null;
    StreamReader sr = null;

    public void Start()
    {
        thread = new Thread(new ParameterizedThreadStart((object context) =>
            {
                SendRequest();
            }));
        thread.IsBackground = true;
        thread.Start();
    }

    public void Abort()
    {            
        if (webResponse != null) webResponse.Close();
        if (webRequest != null) webRequest.Abort();
        if (thread != null) thread.Abort();            
    }

    public void SendRequest()
    {
        webRequest = WebRequest.Create("http://google.com");

        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.Method = "GET";         
       try
        {
            webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
        }
        catch (WebException)
        {
        }
    }

    private void GetResponseCallback(IAsyncResult asynchronousResult)
    {
        try
        {
            webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
            webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
            sr = new StreamReader(webResponse.GetResponseStream());
            string response = sr.ReadToEnd();
            Console.Write(response);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

停止ボタンをクリックしようとすると問題が発生します。フォームがブロックされています。私の停止機能が正しいか間違っているかはわかりません。アドバイスをいただけますか?ありがとう

4

2 に答える 2

0

ハングの考えられる原因は、他の人によって示唆されています。ただし、より重要なことは、Thread.Abort の実際の使用法です。

それは非常に悪いことだと考えられており、それが引き起こす可能性のある問題や微妙なバグの量を信じられないでしょう.

幸いなことに、通常は実際には必要ありません。非同期タスクのタイムリーな完了は、アプリケーション自体で処理できますし、処理する必要があります。たとえば、ユースケースを考えてみましょう:

中止を呼び出すことによって何を達成しようとしていますか? リクエストを中止しようとしていますか? すでに進行中のため、できません。目的地に到着し、相手側で待っている人がいるかどうかに関係なく処理されます。ただし、不要な計算を避けようとしている場合は、完全に制御できます。「abortRequested」という名前のクラスにブール値のメンバーを保持でき、Abort メソッドはそれを「true」に設定します。中止するメソッドは、実行を続行するかどうかを決定するために、このメンバーを時々チェックする必要があります。

必要に応じて、ユースケースをさらに分析できます。

編集:次のようになります。

bool stopped = false; // can make this thread safe if you want.

// Assuming you have a computation in a loop.
compouteAsynch(){

   for(var workItme in workItems){
     if(!stopped){
      dostuff(workItem)
     }
   }
}

void stop(){
   stopped = true; // work will not stop immediately. Only in the next iteration.
}

「停止した」サンプリングの粒度を好きなように制御できます。ただし、どこでもサンプリングできるわけではないことに注意してください。たとえば、スレッドがDBに対してクエリを実行している間はチェックできません。しかし、これで十分なはずです。

于 2012-08-17T09:48:05.680 に答える
0

すでに開始されている可能性のある Web リクエストを同期的に中止しようとしているようです。これらのリクエストの処理が進行中の可能性があるため、この時点でアボート コールが停止している可能性があります。関係なくアボートを呼び出したい場合は、別のワーカー スレッドでこれを実行して、少なくとも GUI が戻るようにすることを検討します。

于 2012-08-17T09:13:22.830 に答える