简体   繁体   English

在单独的线程上重用连接

[英]reuse connection on separate threads

I need to listen to an open API, upon correct data I need to download some file and process it. 我需要听一个开放的API,根据正确的数据,我需要下载一些文件并进行处理。 I am using timer to automatically issue a download request every x seconds which keeps the connection alive, hence available for reuse. 我正在使用计时器每x秒自动发出一次下载请求,以使连接保持活动状态,因此可供重用。

There is a total of 3 components: 共有3个组件:

  1. Parent Class 家长班
  2. Listener Class 侦听器类
  3. Timer 计时器

The parent class spawns the listener on a separate thread, and also initiates the timer. 父类在单独的线程上生成侦听器,并且还启动计时器。 Both, timer and listener invoke a delegate on the parent. 计时器和侦听器都在父级上调用委托。

The problem is that on every download from timer the connection is reused (evident from download time) but when listener invokes the same, it is not. 问题在于,每次从计时器下载时,连接都被重用(从下载时开始可见),但是当侦听器调用连接时,连接不是。

Bare-bone code: 裸骨代码:

using Timer = System.Timers.Timer;

namespace Hallelujah
{
    public delegate void downloadData(bool process, string url);
    public delegate void downloadDataInvoker(bool process, string url);

class Listener2
{
    downloadData _downloadData;
    public void start(string storeID, string shoes)
    {
        ServicePointManager.DefaultConnectionLimit = 500;
        ServicePointManager.Expect100Continue = false;
        ServicePointManager.MaxServicePoints = 0;

        _downloadData += new downloadData(downloadDataCb);

        Timer timer = new Timer(10000);
        timer.Elapsed += timer_Elapsed;
        timer.Enabled = true;

        Listen listenTool = new Listen();
        listenTool._downloadData += new downloadDataInvoker(invoker);

        Thread thread = new Thread(new ParameterizedThreadStart(listenTool.init));
        string[] str = { params };
        thread.Start(str);

        F1.updateStatus(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        _downloadData.Invoke(false, "example.com");
    }

    public void invoker(bool process, string url)
    {
        _downloadData.Invoke(process, url);
    }
    public void downloadDataCb(bool process, string url)
    {
        F1.updateStatus(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        req.KeepAlive = true;
        req.ProtocolVersion = HttpVersion.Version10;
        req.UnsafeAuthenticatedConnectionSharing = true;
        req.Pipelined = true;
        WebResponse res = req.GetResponse();
        Stream sr = res.GetResponseStream();
        //Reading response
        if (process)
        {
            F1.updateStatus("Downloaded  in " + t1.Seconds + " s " + t1.Milliseconds + "ms ");
        }
        else
            F1.updateStatus("Downloaded NULL(from timer) in " + t1.Seconds + " s " + t1.Milliseconds + "ms ");
    }

    public void updateStatusCB(string status)
    {
        F1.updateStatus(status);
    }

}
internal class Listen
{
    public downloadDataInvoker _downloadDataInvoker;
    public updateStatus _updateStatus;
    public bool ToListen = true;

    public void init(object objpass)
    {
        _updateStatus.Invoke(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

         while(ToListen){
            //When a match is found
            _downloadDataInvoker.Invoke(true, media_url);
        }


    }
}

Any idea why is this happening this way? 知道为什么会这样吗?

You create a new keep-alive request when timer event invoked. 当调用计时器事件时,您将创建一个新的保持活动请求。

According to your needs, there are many download task(via user_id?), you can create a keep-alive request per task, and begin the request async, call the update delegate in the callback event. 根据您的需求,有许多下载任务(通过user_id?),您可以为每个任务创建一个保持活动的请求,并开始异步请求,在回调事件中调用更新委托。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM