为什么List从以后的运行中获取额外的会话
本文关键字:获取 会话 运行 为什么 Session 从以后 List | 更新日期: 2023-09-27 18:18:00
我使用fiddlercore捕获会话信息,以便对特定响应中的数据进行比较。我注意到我不理解的一件事是,我将会话信息从第二个环境获取到第一个环境的List集合中。
public class ManageCompares
{
public static string _test2BaseURL = "https://test2/";
public static string _dev1BaseURL = "http://dev1/";
private void RunCompares(string email, string handler, Reporting report)
{
ManageProcess.ShutDownProcess("iexplore");
RunExports exportTest2 = new RunExports();
RunExports exportDev1 = new RunExports();
string password = "d";
List<Session> oAllSessions_Test2 = exportTest2.RunExportGeneration
(email, password, _test2BaseURL, handler);
ManageProcess.ShutDownProcess("iexplore");
List<Session> oAllSessions_Dev1 = exportDev1.RunExportGeneration
(email, password, _dev1BaseURL, handler);
exportTest2.ExtractResponse(oAllSessions_Test2, handler, report);
//report.SetEnvironment2Body(ManageExports.ExtractResponse
// (oAllSessions_Dev1, handler, report, report.Environment2));
if (report.Test2ResponseCode != 500 && report.Dev1ResponseCode != 500)
{
bool matches = CompareExports.CompareExportResults
(report.Environment1Body, report.Environment2Body);
if (matches)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Exports matched");
Console.ResetColor();
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Export does not match");
Console.ResetColor();
report.GenerateReportFiles();
}
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine
("A exception was returned. Please review the log file.");
Console.ResetColor();
}
}
}
public class RunExports
{
public List<Session> RunExportGeneration
(string email, string password, string baseUrl,
string handlersUrlwithParams)
{
IWebDriver driver = new InternetExplorerDriver();
FiddlerApplication.Startup(8877, FiddlerCoreStartupFlags.Default);
List<Session> oAllSessions = new List<Session>();
LoginPage login = new LoginPage(driver);
FiddlerApplication.AfterSessionComplete += delegate(Session oS)
{
Monitor.Enter(oAllSessions);
oAllSessions.Add(oS);
Monitor.Exit(oAllSessions);
};
try
{
driver.Navigate().GoToUrl(baseUrl);
login.LoginToView(email, password);
driver.Navigate().GoToUrl(baseUrl + handlersUrlwithParams);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
FiddlerApplication.Shutdown();
driver.Quit();
}
return oAllSessions;
}
}
List oAllSessions_Test2和List oAllSessions_Dev1是我的两个集合。当我调试捕获时,我通常在oAllSessions_Test2集合中看到15行。然后,在捕获oAllSessions_Dev1之后,我看到计数已经跃升了14或15,当我查看集合中包含的内容时,一些Dev1捕获现在在那里。oAllSessions_Dev1具有我所期望的会话。我猜一定有一个我没有预料到的指针,但我在这一点上如何清理它。我注意到的另一件事是,当应用程序循环处理各种情况时,会话计数器继续增加。
我也使用Selenium WebDriver和IE来启动浏览器会话,但我不认为这与这个特定问题特别相关。
我在这里错过了什么?
这样做:
SessionStateHandler tAction = oS =>
{
Monitor.Enter(oAllSessions);
oAllSessions.Add(oS);
Monitor.Exit(oAllSessions);
};
FiddlerApplication。
......
//在返回语句之前的结尾:
FiddlerApplication.AfterSessionComplete -= tAction;
事情是这样的。
this: FiddlerApplication.Startup(8877, FiddlerCoreStartupFlags.Default);
(特别是)FiddlerApplication
保存外部应用程序(fiddler)中的引用并为您管理它们。当你+=并添加一个委托FiddlerApplication.AfterSessionComplete += tAction;
时,提琴手应用程序将其添加到AfterSession事件触发时调用的方法列表中。
因为它是单例的(在代码中只处理一个Fiddler应用程序实例),所以每次执行a +=时,它都会将其添加到同一个列表中。FiddlerApplication中的这个列表不会在每次调用方法时重新创建。它是你第一次调用的那个,所以即使你的委托超出了它的作用域声明空间(就像局部对象通常在方法中做的那样),fiddlerapplicationeventlist维护对它的引用并每次(以及每一次)触发该委托。
所以…
在你的方法中,你创建List<Session> oAllSessions = new List<Session>();
并在你的委托中访问它。这个局部变量现在被传递回调用方法,List<Session> oAllSessions_Test2 = exportTest2.RunExportGeneration....
和委托FiddlerApplication调用的是完全相同的列表。每次你调用那个功能并且AfterSessionComplete触发时,它会更新列表,即使它已经返回给调用函数。
要阻止它,你必须添加:FiddlerApplication.AfterSessionComplete -= tAction;
,它告诉系统"嘿,不要再向这个方法推送更新了。它已经完成了接收通知。"
在。net语言中,类对象几乎在所有情况下都是通过引用传递的。如果将对象引用赋值给变量,则该变量仍将引用原始对象。对原始文件的更改将通过所有引用可见。这类似于C/c++中在内存中存储结构的指针或引用时发生的事情。实现细节不同,但结果是相同的。
下面是一个例子,当您存储列表实例时,可能会发生更改:
class ListTest
{
List<string> l = new List<string>();
public List<string> GetList() { return l; }
public void Add(string v) { l.Add(v); }
}
class Program
{
static void Main(string[] args)
{
ListTest t = new ListTest();
t.Add("a"); t.Add("b"); t.Add("c"); t.Add("d");
List<string> x1 = t.GetList();
List<string> x2 = t.GetList().ToList();
t.Add("e"); t.Add("f"); t.Add("g"); t.Add("h");
List<string> y1 = t.GetList();
List<string> y2 = t.GetList().ToList();
Console.WriteLine("{0}, {1}", x1.Count, y1.Count);
Console.WriteLine("{0}", string.Join(", ", x1));
Console.WriteLine("{0}", string.Join(", ", y1));
Console.WriteLine();
Console.WriteLine("{0}, {1}", x2.Count, y2.Count);
Console.WriteLine("{0}", string.Join(", ", x2));
Console.WriteLine("{0}", string.Join(", ", y2));
}
}
当你运行它时,你会得到一组相同的结果,因为x1
和y1
是对同一个对象的引用。第二组结果不同,因为对ToList
的调用创建了一个新的List<string>
实例来保存结果。
这可能是Fiddler代码返回的列表发生的情况。
——代码复查后更新
它看起来像是你分配给AfterSessionComplete
事件的委托导致代码将oAllSessions
视为绑定到事件处理程序委托的静态对象。当您开始使用生成闭包等的代码时,会出现各种类似的副作用。
我建议更改代码以使用类方法而不是内联方法-将oAllSessions
变量和分配给AfterSessionComplete
的代码移到类的主体中。这至少可以确定内联委托是否是问题的原因。