0

まず第一に、私は一般的に C# と .NET Framework にまったく慣れていませんが、私が達成しようとしているのは (IMHO の非常に) 単純な目標ですが、まだいくつかの問題に遭遇しています。

私の目標は、WebRequestクラスを使用してデータを Web サービスに POST することです。ドキュメントと例、特にこの部分を読みました。

BeginGetRequestStream メソッドでは、このメソッドが非同期になる前に、いくつかの同期セットアップ タスク (DNS 解決、プロキシ検出、TCP ソケット接続など) を完了する必要があります。結果として、このメソッドはユーザー インターフェイス (UI) スレッドで呼び出されるべきではありません。これは、通常は数秒かかる場合があるためです。

GetRequestStreamCallbackリンクされた例を参照して、メソッドを作成GetResponseCallbackしてバックグラウンド スレッドで実行するにはどうすればよいですか?

これは私がこれまでに得たものです:

private void startTask()
        {
            BackgroundWorker worker = new BackgroundWorker();

            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerAsync();
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            updateStatus(e.ProgressPercentage);
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            postData = /* data to be posted */;
            byte[] postBytes = Encoding.UTF8.GetBytes(postData);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://example.com");
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postBytes.Length;
            request.Method = "POST";

            request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
        }

        private void GetRequestStreamCallback(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;

            using (Stream stream = request.EndGetRequestStream(result))
            {
                stream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetBytes(postData).Length);
                stream.Close();
            }

            request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
        }

        private void GetResponseCallback(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
            Console.WriteLine(response.StatusDescription);
        }

私が a を使用した理由はBackgroundWorker、UI を操作するためですが、別の解決策も受け入れています。私の質問は、実行フローがworker_DoWork関数の最後に到達したときにワーカーが終了するかどうかです。それとも、コールバック関数でさえワーカー自体によって実行されますか? そうでない場合、このコード全体を別のスレッドで実行する代替手段はありますか?

(おそらく) ばかげた質問で申し訳ありませんが、前述したように、私は .NET にまったく慣れていないため、スレッド化とスレッド プールの概念をまだ理解していません。

4

1 に答える 1

2

BackgroundWorker スレッドは DoWork 関数の最後で完了し、BackgroundWorker を開始したスレッドで RunWorkerCompleted を発生させます。

あなたの例では、request.BeginGetRequestStream を呼び出したスレッドが DoWork の最後にプールに戻るため、GetResponseCallback は別のスレッドで実行されます。

簡単にするために、もう UI スレッドにいないため、同期バージョンまたは要求/応答メソッド (request.GetRequestStream など) を使用できます。UI スレッドは RunWorkedCompleted をリッスンして、UI スレッド内から呼び出しの結果を取得できます。

于 2012-06-14T21:12:45.583 に答える