Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在C中向线程池添加队列任务#_C#_Queue_Threadpool_Add_Task - Fatal编程技术网

C# 如何在C中向线程池添加队列任务#

C# 如何在C中向线程池添加队列任务#,c#,queue,threadpool,add,task,C#,Queue,Threadpool,Add,Task,我还是个新手。假设我有50000个URL,我想同时获得这些URL的内容,就像每10个URL一起处理一样。然后,一旦其中一个URL完成处理,程序应该从队列列表中添加另一个1,直到完成处理列表中的所有URL为止。现在我怎样才能用C#。。以下是我目前正在执行的代码 class RequestState { public WebRequest Request; // holds the request public objec

我还是个新手。假设我有50000个URL,我想同时获得这些URL的内容,就像每10个URL一起处理一样。然后,一旦其中一个URL完成处理,程序应该从队列列表中添加另一个1,直到完成处理列表中的所有URL为止。现在我怎样才能用C#。。以下是我目前正在执行的代码

 class RequestState
        {
            public WebRequest Request;

        // holds the request 
        public object Data;

        // store any data in this 
        public string SiteUrl;

        // holds the UrlString to match up results (Database lookup, etc). 

        public RequestState(WebRequest request, object data, string siteUrl)
        {
            this.Request = request;
            this.Data = data;
            this.SiteUrl = siteUrl;
        }
    }

    private void PROCESS_URLS_Click(object sender, EventArgs e)
    {
        //run the process
        process_URLs();
    }

private int ThreadsCount = 0;

  private void process_URLs()
    {
       //count threads number
        ThreadsCount = URLS_LISTVIEW.SelectedItems.Count;

       //loop through all URLs in listview
        for (int i = 0; i < URLS_LISTVIEW.SelectedItems.Count; i++)
        {
            try
            {
                //get url string
                string myURLs = URLS_LISTVIEW.SelectedItems[i].SubItems[0].Text.Trim();

                // for each URL in the collection...
                WebRequest request = HttpWebRequest.Create(myURLs);
                request.Method = "GET";
                object data = new object();

                RequestState state = new RequestState(request, data, myURLs);
                IAsyncResult result = request.BeginGetResponse(new AsyncCallback(UpdateItem), state);
                ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), state, (30 * 1000), true);

            }
            catch (ThreadStateException es)
            {
                MessageBox.Show(es.Message);
            }

        }



    }




 private void UpdateItem(IAsyncResult result)
    {
        RequestState state = (RequestState)result.AsyncState;
        WebRequest request = (WebRequest)state.Request;
        try
        {// grab the custom state object
            // get the Response
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

            // process the response...
            Stream s = (Stream)response.GetResponseStream();
            StreamReader readStream = new StreamReader(s);

            //data grabbed
            string dataString = readStream.ReadToEnd();
            response.Close();
            s.Close();
            readStream.Close();



        //finished grabbing content for this thread.
        ThreadsCount = ThreadsCount - 1;


        //if all threads finished running then execute final code to tell the user the process finished
        if (ThreadsCount < 1)
        {
            //show message
            MessageBox.Show("finished");
        }

       // Thread.Sleep(400);

    }





private static void ScanTimeoutCallback(object state, bool timedOut)
    {
        if (timedOut)
        {
            RequestState reqState = (RequestState)state;

            if (reqState != null)
                reqState.Request.Abort();


        }
    }
类请求状态
{
公共网络请求;
//保留请求
公共对象数据;
//将任何数据存储在此数据库中
公共字符串SiteUrl;
//保存URL字符串以匹配结果(数据库查找等)。
公共请求状态(WebRequest请求、对象数据、字符串siteUrl)
{
this.Request=请求;
这个。数据=数据;
this.SiteUrl=SiteUrl;
}
}
私有无效进程\u URL\u单击(对象发送方,事件参数e)
{
//运行进程
处理URL();
}
私有int-threadscont=0;
私有无效进程\u URL()
{
//计算线程数
threadscont=url\u LISTVIEW.SelectedItems.Count;
//循环浏览listview中的所有URL
对于(int i=0;i
如有任何想法,将不胜感激:)


您好,

看看TPL,有一个选项可以指定最大并行度:

List<string> UriList = new List<string>();
...
Parallel.ForEach(UriList, 
                 new ParallelOptions() {MaxDegreeOfParallelism=10}, 
                 (x) =>
{
    ProcessUrl(x);
});
这不是为了制造更多的混乱,但在您的特定情况下也会很好地工作,因为要处理的项目之间没有依赖关系,并且您有一个实际结果,即URL被“转换”为:

(这应该是@BrokenGlass下的评论,但我还不能发表评论)

您可以了解如何使用并行处理和PLINQ来完成所需的工作。前面的一整套文章也提供了一些很好的信息

编辑:如果这是独立的,则生成一个新线程以在后台运行此部分,这样不会导致UI无响应


编辑2:如果你愿意,你也可以将你的字符串放入一个列表中,这样你就可以在查找它们的同时从UI中添加项目。

这意味着我需要从头开始编写整个内容?你仍然可以重复使用实际处理Url的代码,如
WebRequest
等。但就我个人而言,我甚至可以通过使用
WebClient。想想长远的好处吧——要维护的代码要少得多。@ERMC2014:更新了一个示例谢谢:)…但是现在当我运行代码时,整个UI冻结,直到它从50个URL抓取完所有内容为止。有什么想法吗?@ERMC2014:the
Parallel.Foreach()
语句只有在下载完所有内容后才会完成-它是同步的。如果您希望它是异步的,您必须生成一个线程来运行它,即将它包装到
任务中。
。您的意思是我需要使用一个新线程来完成这项任务,还是使用后台工作程序?或者两者都做相同的事情并不重要。@ermac2014-您可以o或者。只需将工作转移到与您的UI无关的其他线程即可避免挂起。然后,当工作完成后,只需通过回调将结果更新UI。现在这很有意义:)如果我需要进一步的帮助,我会让您知道。非常感谢您提供的提示。不用担心!如果可以,我很高兴提供援助。
List<string> UriList = new List<string>();
for(int i =0;i<50;i++)
    UriList.Add("http://google.com");

string[] HtmlResults = new string[UriList.Count];

Parallel.ForEach(UriList, 
                 new ParallelOptions() { MaxDegreeOfParallelism = 10 }, 
                 (url, i, j) =>
{
    WebClient wc = new WebClient();
    HtmlResults[j] = wc.DownloadString(url);
});
var htmlResultList = UriList.AsParallel()
                            .WithDegreeOfParallelism(10)
                            .AsOrdered()
                            .Select(url => { WebClient wc = new WebClient(); return wc.DownloadString(url); })
                            .ToList();