C#WinForm连续多个连续的线程Web请求

时间:2015-03-05 09:17:58

标签: c# multithreading winforms web-services

我使用Visual Studio 2012在C#(WinForm)中编写了一个小工具。

其目的是让用户针对数据库检查给定的城市和邮政编码,以验证城市/邮编组合是否合法。

到目前为止一切正常(请参阅下面的简化代码)。由于用户可能同时执行多个验证,我使用了队列模式(为了确保,我按照正确的顺序发送多个请求,因为它们已经提交)。

现在,我需要修改我的代码以运行3个Web请求以获得相同的结果。

我不需要直接使用城市和邮政编码查询网络服务,而是需要按顺序发出3个请求:

  1. 将代码发送到网络服务器X 以请求密钥
  2. 将获得的密钥发送到 webserver X 以验证城市和邮政编码
  3. 将验证结果发送至网络服务器Y 以保存城市和邮政编码。
  4. 显然,我必须先等待第一个请求才能继续执行第二个请求,等等......我需要检查第二个请求是否返回true / valid否则我不会需要保存/执行第三个请求。

    我需要有关如何在我的代码中包含这两个Web请求而不破坏我的队列机制的帮助。我的队列中的一个项目现在应该包含3个请求,同时确保我没有在步骤1或步骤2之前请求步骤2或3已经发送了(有效)结果。

    这是我到目前为止所得到的:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Mail;
    using System.Text;
    using System.Threading;
    using System.Web;
    using System.Xml;
    using System.Globalization;
    using System.Security.Cryptography;
    using System.Windows.Forms;
    using CheckAddress.Util;
    
    namespace CheckAddress.Api
    {
        public class ApiHelper
        {
            #region singleton
            private static ApiHelper _instance;
            private static Object _lock = new object();
    
            public static ApiHelper Instance
            {
                get
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new ApiHelper();
                        }
                    }
                    return _instance;
                }
            }
            #endregion
    
            private Thread _queueThread;
            private bool _running;
            private Queue<Address> _queue;
    
            private ApiHelper()
            {
                _running = false;
                _queue = new Queue<Address>();
    
                MaxThreads = SettingsFile.Instance.MaxThreads;
                MaxAttempts = SettingsFile.Instance.MaxAttempts;
    
                ThreadPool.SetMaxThreads(MaxThreads, MaxThreads);
            }
    
            public int MaxThreads { get; set; }
            public int MaxAttempts { get; set; }
    
            public void Add(Address a)
            {
                lock (_queue)
                {
                    _queue.Enqueue(a);
                }
            }
    
            private void AddressSendProc(object state)
            {
                bool isValid = false;
    
                foreach (Address.CityZIP theCityZIP in a.listOfAddresses)
                {
                    while (!success && tries < MaxAttempts)
                    {
                        try
                        {
                            var req = (HttpWebRequest)WebRequest.Create("http://domain.com/geo.php?city=auburn&zip=95602");
                            req.Method = "GET";
    
                            req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0";
                            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                            req.ContentType = "application/x-www-form-urlencoded";
    
                            req.Timeout = 3000;
                            var resp = (HttpWebResponse)req.GetResponse();
    
                            var ms = new MemoryStream();
                            var rs = resp.GetResponseStream();
                            if (rs != null)
                            {
                                var buf = new byte[4096];
                                int len = 0;
                                while ((len = rs.Read(buf, 0, buf.Length)) > 0)
                                {
                                    ms.Write(buf, 0, len);
                                }
                                rs.Close();
                            }
    
                            var xml = new XmlDocument();
                            xml.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
                            var nodes = xml.SelectNodes("/response/valid");
                            if (nodes.Count == 1)
                            {
                                isValid = true;
                            }
                            int code = 0;
                            Int32.TryParse(nodes[0].InnerText, out code);
    
                            if (code == 200)
                            {
                                success = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            /* */
                        }
                        tries++;
                    }
                }
            }
    
            private void ApiThreadProc()
            {
                while (_running)
                {
                    try
                    {
                        lock (_queue)
                        {
                            while (_queue.Count > 0)
                            {
                                ThreadPool.QueueUserWorkItem(AddressSendProc, _queue.Dequeue());
                            }
                        }
                        Thread.Sleep(1000);
                    }
                    catch (Exception) {/*ignore*/}
                }
            }
    
            public void Start()
            {
                _running = true;
                _queueThread = new Thread(ApiThreadProc);
                _queueThread.Start();
            }
    
            public void Stop()
            {
                _running = false;
                if (_queueThread != null)
                {
                    _queueThread.Interrupt();
                }
            }
        }
    }
    

0 个答案:

没有答案