请教一个关于winFrom多线程HttpWebRequest数据的问题

postGetWeb 2015-09-02 04:36:27
上代码demo

//委托
private delegate void DgtGetRequest(object web);
DgtGetRequest dgtrequest = new DgtGetRequest(GetHttp);

//点击按钮一时执行
hread th = new Thread(new ParameterizedThreadStart(ThreadGetResquest));
th.Start("https://www.baidu.com/");


//请求web,获得返回数据,显示在treeView1,
public void GetHttp(object web) {
WebRequest request = WebRequest.Create(((string)web));
WebResponse response = request.GetResponse();
string str = new StreamReader(response.GetResponseStream(), Encoding.UTF8).ReadToEnd();
treeView1.Nodes.Add(str);
}

使用上面的方式会导致winform界面卡住(假死)
问题是这样的,我请求的api返回的json,需要放在 treeView1中显示,而且会循环请求很多次,所以必须要用的多线程
而我也试了

Control.CheckForIllegalCrossThreadCalls = false;
//然后点击按钮时执行
Thread th = new Thread(new ParameterizedThreadStart(GetHttp));
th.Start("https://www.baidu.com/");
//执行到下面这句会报错
//在该控件上执行的操作正从错误的线程调用。
//使用 Control.Invoke 或 Control.BeginInvoke 封送到正确的线程才能执行此操作。
treeView1.Nodes.Add(str);

有什么办法解决界面卡的问题
...全文
264 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
泡泡龙 2015-09-06
  • 打赏
  • 举报
回复
[quote=引用 10 楼 zhuankeshumo 的回复:] 这样 [code=csharp] CookieContainer cookie = new CookieContainer(); Dictionary<string, string> parameters = new Dictionary<string, string>(); Dictionary<string, string> dics = new Dictionary<string, string>(); dics.Add("begintime", begintime.ToString("yyyy-MM-dd")); dics.Add("endtime", endtime.ToString("yyyy-MM-dd")); parameters.Add("json", JsonConvert.SerializeObject(dics).ToString()); var task1 = HttpHelper.CreatePostHttpResponse(System.Configuration.ConfigurationManager.AppSettings["GetWorkSationOrderAndCustomer"].ToString(), parameters, "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16", Encoding.UTF8, cookie); var content = ""; allWorkSationOC.WorkSationOCInfos = new List<WorkSationOCInfo>(); using (Stream stream = task1.Result.GetResponseStream()) { using (StreamReader sr = new StreamReader(stream)) { content = sr.ReadToEnd(); allWorkSationOC.WorkSationOCInfos = JsonConvert.DeserializeObject<List<WorkSationOCInfo>>(content); } } using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace ShiHang.Infrastructure { public class HttpHelper { private static readonly string DefaultUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16"; /// <summary> /// 创建POST方式的HTTP请求 /// </summary> /// <param name="url">请求的URL</param> /// <param name="parameters">随同请求POST的参数名称及参数值字典</param> /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param> /// <param name="requestEncoding">发送HTTP请求时所用的编码</param> /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param> /// <returns></returns> public static Task<WebResponse> CreatePostHttpResponse(string url, IDictionary<string, string> parameters, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer) { if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } if (requestEncoding == null) { throw new ArgumentNullException("requestEncoding"); } HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; if (!string.IsNullOrEmpty(userAgent)) { request.UserAgent = userAgent; } else { request.UserAgent = DefaultUserAgent; } if (cookieContainer == null) { request.CookieContainer = new CookieContainer(); } else { request.CookieContainer = cookieContainer; } //如果需要POST数据 if (!(parameters == null || parameters.Count == 0)) { StringBuilder buffer = new StringBuilder(); int i = 0; foreach (string key in parameters.Keys) { if (i > 0) { buffer.AppendFormat("&{0}={1}", key, parameters[key]); } else { buffer.AppendFormat("{0}={1}", key, parameters[key]); } i++; } byte[] data = requestEncoding.GetBytes(buffer.ToString()); var task = Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, request, TaskCreationOptions.None); //等待任务完成 task.Wait(); //执行完本任务后再连续执行写入留和返回response对象 ' using (Stream stream = task.Result)//如果上面没有等待任务完成那一句,在这里直接获取结果也是可以的 { stream.Write(data, 0, data.Length); } } return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, request, TaskCreationOptions.None); } 你这个代码如果发生采集错误,如何释放资源呢?
newtee 2015-09-03
  • 打赏
  • 举报
回复
newtee 2015-09-03
  • 打赏
  • 举报
回复
这样

            CookieContainer cookie = new CookieContainer();
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            Dictionary<string, string> dics = new Dictionary<string, string>();
            dics.Add("begintime", begintime.ToString("yyyy-MM-dd"));
            dics.Add("endtime", endtime.ToString("yyyy-MM-dd"));
            parameters.Add("json", JsonConvert.SerializeObject(dics).ToString());
            var task1 = HttpHelper.CreatePostHttpResponse(System.Configuration.ConfigurationManager.AppSettings["GetWorkSationOrderAndCustomer"].ToString(), parameters,
                    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16",
                    Encoding.UTF8,
                    cookie);
            var content = "";
            allWorkSationOC.WorkSationOCInfos = new List<WorkSationOCInfo>();
            using (Stream stream = task1.Result.GetResponseStream())
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    content = sr.ReadToEnd();
                    allWorkSationOC.WorkSationOCInfos = JsonConvert.DeserializeObject<List<WorkSationOCInfo>>(content);
                }
            }

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ShiHang.Infrastructure
{
    public class HttpHelper
    {
        private static readonly string DefaultUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16";
        /// <summary>         
        /// 创建POST方式的HTTP请求          
        /// </summary>         
        /// <param name="url">请求的URL</param>          
        /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>          
        /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>         
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>         
        /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param>    
        /// <returns></returns>         
        public static Task<WebResponse> CreatePostHttpResponse(string url, IDictionary<string, string> parameters, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            if (requestEncoding == null)
            {
                throw new ArgumentNullException("requestEncoding");
            }
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            else
            {
                request.UserAgent = DefaultUserAgent;
            }
            if (cookieContainer == null)
            {
                request.CookieContainer = new CookieContainer();
            }
            else
            {
                request.CookieContainer = cookieContainer;
            }
            //如果需要POST数据             
            if (!(parameters == null || parameters.Count == 0))
            {
                StringBuilder buffer = new StringBuilder();
                int i = 0;
                foreach (string key in parameters.Keys)
                {
                    if (i > 0)
                    {
                        buffer.AppendFormat("&{0}={1}", key, parameters[key]);
                    }
                    else
                    {
                        buffer.AppendFormat("{0}={1}", key, parameters[key]);
                    }
                    i++;
                }
                byte[] data = requestEncoding.GetBytes(buffer.ToString());
                var task = Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, request, TaskCreationOptions.None);               //等待任务完成               
                task.Wait();                //执行完本任务后再连续执行写入留和返回response对象           '
                using (Stream stream = task.Result)//如果上面没有等待任务完成那一句,在这里直接获取结果也是可以的           
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, request, TaskCreationOptions.None);
        }

        /// <summary>          
        /// 创建GET方式的HTTP请求        
        /// </summary>        
        /// <param name="url">请求的URL</param>          
        /// <param name="timeout">请求的超时时间</param>         
        /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>       
        /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param>         
        /// <returns></returns>        
        public static Task<WebResponse> CreateGetHttpResponse(string url, string userAgent, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
            request.Method = "GET";
            request.UserAgent = DefaultUserAgent;
            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            if (cookieContainer == null)
            {
                request.CookieContainer = new CookieContainer();
            }
            else
            {
                request.CookieContainer = cookieContainer;
            }
            return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, request, TaskCreationOptions.None);
        }
    }
}

配置 <system.net> <connectionManagement> <add address="*" maxconnection="512"/> </connectionManagement> <defaultProxy enabled="false" useDefaultCredentials="false" > <proxy/> <bypasslist/> <module/> </defaultProxy> </system.net>
ji983546935 2015-09-02
  • 打赏
  • 举报
回复
结贴给分吧
ji983546935 2015-09-02
  • 打赏
  • 举报
回复
线程中请求web ,委托添加Node,把请求结果作为委托参数,异步执行委托,既不会卡,也不会报错!

private void ThreadGetResquest(object hostIP)
        {
            for (int i = 0; i < 50; i++)
            {
                WebRequest request = WebRequest.Create(((string)hostIP));
                WebResponse response = request.GetResponse();
                Stream stream = response.GetResponseStream();
                string str = new StreamReader(stream, Encoding.UTF8).ReadToEnd();
                response.Close();
                stream.Close();
                dgtrequest = new DgtGetRequest(AddNode);
                //this.Invoke(dgtrequest, str);
                this.BeginInvoke(dgtrequest, str);
            }
        }

        public void AddNode(object web)
        {
            textBox1.Text = web.ToString();
            treeView1.Nodes.Add(web.ToString());
        }
postGetWeb 2015-09-02
  • 打赏
  • 举报
回复
链接: http://pan.baidu.com/s/1qW3O024 密码: 7ugm 这是我Demo的源码,编译之后就可以运行了
postGetWeb 2015-09-02
  • 打赏
  • 举报
回复
引用 5 楼 qq807081817 的回复:
我建议是,先生成一个node实例,所有的数据存到这里,等处理完成之后,再直接treeview1.node = node
不是绑定数据到treeview的问题,是执行GetHttp 方法的时候winfrom界面会卡, 使用后面非安全线程Control.CheckForIllegalCrossThreadCalls = false; 界面不会卡,但是绑定数据会报错
Forty2 2015-09-02
  • 打赏
  • 举报
回复
public void GetHttp(object web)
{
    WebRequest request = WebRequest.Create(((string)web));
    WebResponse response = request.GetResponse();
    string str = new StreamReader(response.GetResponseStream(), Encoding.UTF8).ReadToEnd();
    this.BeginInvoke((Action)delegate
    {
        treeView1.Nodes.Add(str);
    });
}

private void ThreadGetResquest(object web)
{
    ThreadPool.QueueUserWorkItem(GetHttp, web);
}
涛锅 2015-09-02
  • 打赏
  • 举报
回复
我建议是,先生成一个node实例,所有的数据存到这里,等处理完成之后,再直接treeview1.node = node
  • 打赏
  • 举报
回复
WebRequest我记得好像封装有异步方法的,你用异步方式+回调显示也可以
  • 打赏
  • 举报
回复
查BackgroundWork的用法 或者用4.0里的Task也很方便
postGetWeb 2015-09-02
  • 打赏
  • 举报
回复
上面的代码还少了一个方法

 private void ThreadGetResquest(object  web)
 {
            this.Invoke(dgtrequest, web);
 }

110,501

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧