Коллекция не изменена, операция перечисления может не выполняться - в mschart

Я использую Fiddler API. В этом API я использую событие AfterSessionComplete. Это событие возникает, когда я захожу на любую страницу браузера. Это событие также вызывает метод т.е.drawGraph_2(List<Fiddler.Session>)). Метод обладает функциональностью рисования графика. Я делюсь с вами кодом. Для нескольких запросов я могу нарисовать график, но как только я получаю доступ к слишком большому количеству страниц, я получаю эту ошибку, т.е. коллекция изменяется.

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Windows.Forms;
    using Fiddler;
    using System.Threading;

namespace MSRealTime
{
public partial class Form1 : Form
{
    static int i = 0;
    List<Fiddler.Session> fs = new List<Session>();
    int iSecureEndpointPort = 8877, get = 0, post = 0, threshold_value = 0;
    string sSecureEndpointHostname = "localhost";
    Proxy oSecureEndpoint;
    static int k = 0;
    TimeSpan cbr, sbr, cdr;
    double rt, request_response_time;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        List<Fiddler.Session> numb = new List<Session>();
        //List<Fiddler.Session> removeprev = new List<Fiddler.Session>();
        #region AttachEventListeners
        Fiddler.FiddlerApplication.BeforeRequest += delegate (Fiddler.Session oS)
        {
            oS.bBufferResponse = false;
            Monitor.Enter(numb);
            numb.Add(oS);
            Monitor.Exit(numb);
            oS["X-AutoAuth"] = "(default)";
        };
        //this event fires when server response received by fiddler
        Fiddler.FiddlerApplication.BeforeResponse += delegate (Fiddler.Session oS)
        {
            string s = oS.PathAndQuery;
            int i = oS.port;
        };
        //this event fires when a session has been completed
        Fiddler.FiddlerApplication.AfterSessionComplete += delegate (Fiddler.Session oS)
        {
            //URLMonInterop.SetProxyInProcess("127.0.0.1:8888", "<-loopback>");
            CheckForIllegalCrossThreadCalls = false;
            if (oS.HTTPMethodIs("CONNECT")) { return; }
            else
            {
                label1.Text = numb.Count.ToString();
            }

            //Monitor.Enter(numb);
            numb.Add(oS);
            //removeprev.Add(oS);
            numb = numb.OrderBy(x => x.id).ToList();
            // Monitor.Exit(numb);
            //numb.Add(TimeSpan.Parse(oS.Timers.ClientBeginRequest.ToString()).TotalMilliseconds-TimeSpan.Parse(oS.Timers.ClientBeginRequest.ToString()).TotalMilliseconds);
            drawGraph_2(numb);
            //numb.Clear();
        };
        #endregion AttachEventListeners
        //Fiddler.CONFIG.IgnoreServerCertErrors = true;
        FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
        try
        {
            Fiddler.FiddlerApplication.Startup(iSecureEndpointPort, oFCSF);
        }
        catch (Exception exe) { MessageBox.Show(exe.Message); }
        FiddlerApplication.Log.LogFormat("Created endpoint listening on port {0}", iSecureEndpointPort);
        FiddlerApplication.Log.LogFormat("Starting with settings: [{0}]", oFCSF);
        FiddlerApplication.Log.LogFormat("Gateway: {0}", CONFIG.UpstreamGateway.ToString());
        oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);

    }
    private void drawGraph_2(List<Fiddler.Session> numb)
    {
        //for (; i < numb.Count; i++)
        //{
        //    fs[i] = numb[i];
        //}
        fs = numb;
        //foreach (Session fs in numb)
        for(;i<fs.Count;i++)
        {
            cbr = fs[i].Timers.ClientBeginRequest.TimeOfDay;
            sbr = fs[i].Timers.ServerBeginResponse.TimeOfDay;
            cdr = fs[i].Timers.ClientDoneResponse.TimeOfDay;
            double cbr_millisecond = TimeSpan.Parse(cbr.ToString()).TotalMilliseconds;
            double sbr_millisecond = TimeSpan.Parse(sbr.ToString()).TotalMilliseconds;
            double cdr_millisecond = TimeSpan.Parse(cdr.ToString()).TotalMilliseconds;
            rt = (cdr_millisecond - cbr_millisecond);                                                                           // page response time
            request_response_time = (sbr_millisecond - cbr_millisecond);                                                          // request response time
            // Add point.
            chart1.Series["Series1"].Points.AddXY(fs[i].id, rt);
        }
    }
}

1 ответ

Ваше событие AfterSessionCompleteсрабатывает быстрее, чем ваш код обработчика может его обработать. Таким образом, ваша коллекция изменяется, пока вы все еще выполняете ее.

Вам нужно будет сделать копию, чтобы иметь коллекцию, которая не изменяется.

Вы можете сделать это, позвонив ToList на это, как предложено:

fs = numb.ToList();

Так как в любом случае вы, похоже, потом обрабатываете его как массив, вы также можете сразу создать массив:

fs = numb.ToArray();
Другие вопросы по тегам