Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.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# web应用程序中的BeginGetResponse_C#_Multithreading_.net 3.5 - Fatal编程技术网

C# web应用程序中的BeginGetResponse

C# web应用程序中的BeginGetResponse,c#,multithreading,.net-3.5,C#,Multithreading,.net 3.5,我想使用BeginGetResponse方法来调用列表中的许多URL。 关于如何实施这一点,我有两个问题: 根据中的示例 我们使用: public static ManualResetEvent allDone= new ManualResetEvent(false); 在web应用程序中使用静态成员是否明智,因为它与其他线程共享?这会导致问题吗 我怎么知道所有回调何时完成?我需要对结果做一个总结报告 谢谢我想你是想做这样的事情: int total = urls.Count; ManualR

我想使用BeginGetResponse方法来调用列表中的许多URL。 关于如何实施这一点,我有两个问题:

  • 根据中的示例
  • 我们使用:

    public static ManualResetEvent allDone= new ManualResetEvent(false);
    
    在web应用程序中使用静态成员是否明智,因为它与其他线程共享?这会导致问题吗

  • 我怎么知道所有回调何时完成?我需要对结果做一个总结报告

  • 谢谢

    我想你是想做这样的事情:

    int total = urls.Count;
    ManualResetEvent evt = new ManualResetEvent();
    ConcurrentBag<WebResponses> responses = new ConcurrentBag<WebResponse>();
    
    foreach(Uri in uri)
    {
        HttpWebRequest req = ...;
        req.BeginGetResponse(res=>
        {
            WebResponse res = req.EndGetResponse();
    
            // do what you need with the response.
            // maybe add it to a collection so you can report on it later:
            responses.Add(res);
    
            if(Interlocked.Decrement(ref total) == 0)
            {
                // this was the last response. set event.
                evt.Set();
            }
        }, null);
    }
    
    evt.Wait();
    
    foreach(WebResponse res in responses)
    {
        // report something about the response.
    }
    
    inttotal=url.Count;
    ManualResetEvent evt=新的ManualResetEvent();
    ConcurrentBag响应=新ConcurrentBag();
    foreach(Uri中的Uri)
    {
    HttpWebRequest请求=。。。;
    请求开始响应(res=>
    {
    WebResponse res=req.EndGetResponse();
    //做你需要的回应。
    //可能会将其添加到集合中,以便以后可以报告:
    答复.添加(res);
    if(联锁减量(参考总数)==0)
    {
    //这是最后一次响应。设置事件。
    evt.Set();
    }
    },空);
    }
    evt.Wait();
    foreach(响应中的WebResponse res)
    {
    //报告一些关于反应的情况。
    }
    
    请注意,最佳工作流不需要事件。为了获得额外的积分,将所有这些都去掉,并将您的最终逻辑移动到设置事件的if中


    此外,此代码未经测试且缺少错误处理,因此如果您使用它,请务必将其添加到代码中。

    我猜您正在尝试这样做:

    int total = urls.Count;
    ManualResetEvent evt = new ManualResetEvent();
    ConcurrentBag<WebResponses> responses = new ConcurrentBag<WebResponse>();
    
    foreach(Uri in uri)
    {
        HttpWebRequest req = ...;
        req.BeginGetResponse(res=>
        {
            WebResponse res = req.EndGetResponse();
    
            // do what you need with the response.
            // maybe add it to a collection so you can report on it later:
            responses.Add(res);
    
            if(Interlocked.Decrement(ref total) == 0)
            {
                // this was the last response. set event.
                evt.Set();
            }
        }, null);
    }
    
    evt.Wait();
    
    foreach(WebResponse res in responses)
    {
        // report something about the response.
    }
    
    inttotal=url.Count;
    ManualResetEvent evt=新的ManualResetEvent();
    ConcurrentBag响应=新ConcurrentBag();
    foreach(Uri中的Uri)
    {
    HttpWebRequest请求=。。。;
    请求开始响应(res=>
    {
    WebResponse res=req.EndGetResponse();
    //做你需要的回应。
    //可能会将其添加到集合中,以便以后可以报告:
    答复.添加(res);
    if(联锁减量(参考总数)==0)
    {
    //这是最后一次响应。设置事件。
    evt.Set();
    }
    },空);
    }
    evt.Wait();
    foreach(响应中的WebResponse res)
    {
    //报告一些关于反应的情况。
    }
    
    请注意,最佳工作流不需要事件。为了获得额外的积分,将所有这些都去掉,并将您的最终逻辑移动到设置事件的if中


    此外,此代码未经测试且缺少错误处理,因此,如果您使用它,请务必将其添加到中。

    虽然您可以使用事件,但我建议使用和之类的:

    请注意,上面返回的是一个通知,您必须等待或在完成后继续(如果您担心通知)

    如果您使用的是.NET 4.5,则不需要在
    TaskFactory
    类上使用
    continuewhalll
    方法,但可以在
    Task
    类上使用来执行工作:

    // Note that work does not start here yet because of deferred execution.
    // If you want it to start here, you can call ToArray like above.
    IEnumerable<Task<WebResponse>> tasks = uris.Select(u => {
        // Create the request.
        WebRequest req = ...;
    
        // Make the call to return the response asynchronously with
        // a Task.
        return Task.Factory.FromAsync(req.BeginGetResponse,
            req.EndGetResponse, null);
    });
    
    // Execution will start at this call:
    Task<Task<WebRequest>[]> allTasks = Task.WhenAll(tasks);
    
    // Continue or wait here.
    
    //请注意,由于延迟执行,工作尚未在此处开始。
    //如果你想从这里开始,你可以像上面那样给ToArray打电话。
    IEnumerable tasks=uris.Select(u=>{
    //创建请求。
    WebRequest-req=。。。;
    //调用以异步返回响应
    //任务。
    返回Task.Factory.fromsync(req.BeginGetResponse,
    req.EndGetResponse,null);
    });
    //执行将从此调用开始:
    Task allTasks=Task.WhenAll(任务);
    //继续或在这里等待。
    


    请注意,上面是以前的内容。

    虽然您可以使用事件,但我建议您使用和,诸如此类:

    请注意,上面返回的是一个通知,您必须等待或在完成后继续(如果您担心通知)

    如果您使用的是.NET 4.5,则不需要在
    TaskFactory
    类上使用
    continuewhalll
    方法,但可以在
    Task
    类上使用来执行工作:

    // Note that work does not start here yet because of deferred execution.
    // If you want it to start here, you can call ToArray like above.
    IEnumerable<Task<WebResponse>> tasks = uris.Select(u => {
        // Create the request.
        WebRequest req = ...;
    
        // Make the call to return the response asynchronously with
        // a Task.
        return Task.Factory.FromAsync(req.BeginGetResponse,
            req.EndGetResponse, null);
    });
    
    // Execution will start at this call:
    Task<Task<WebRequest>[]> allTasks = Task.WhenAll(tasks);
    
    // Continue or wait here.
    
    //请注意,由于延迟执行,工作尚未在此处开始。
    //如果你想从这里开始,你可以像上面那样给ToArray打电话。
    IEnumerable tasks=uris.Select(u=>{
    //创建请求。
    WebRequest-req=。。。;
    //调用以异步返回响应
    //任务。
    返回Task.Factory.fromsync(req.BeginGetResponse,
    req.EndGetResponse,null);
    });
    //执行将从此调用开始:
    Task allTasks=Task.WhenAll(任务);
    //继续或在这里等待。
    

    请注意,上面的内容是以前的

  • 如果您想在主线程中等待完成,那么这个解决方案不是很好。第一个请求将事件的状态更改为“设置”。因此,主线程将在第一个请求完成后继续执行
  • A建议您使用:

    您必须将对countdownEvent的引用存储在RequestState中。另外,不要忘记控制超时-使用
    ThreadPool.RegisterWaitForSingleObject
    启动新线程

  • 如果您想在主线程中等待完成,那么这个解决方案不是很好。第一个请求将事件的状态更改为“设置”。因此,主线程将在第一个请求完成后继续执行
  • A建议您使用:

    您必须将对countdownEvent的引用存储在RequestState中。另外,不要忘记控制超时-使用
    ThreadPool.RegisterWaitForSingleObject
    启动新线程


  • 嗨,卡斯珀。不幸的是,我使用的是.NET3.5,但很高兴知道还有一些东西需要等待:)你能解释一下吗?如何使用这种方法获取请求的响应?嗨,卡斯珀。不幸的是,我使用的是.NET3.5,但很高兴知道还有一些东西需要等待:)你能解释一下吗?如何使用此方法获取请求的响应?
       using(var countdownEvent = new CountdownEvent(list.Count))
       {
           // launch requests with countdownEvent.Signal(); in the end
           countdownEvent.Wait();
       }