मैं यूआई स्वचालन के माध्यम से अपने आवेदन के स्वचालित परीक्षण करने की कोशिश कर रहा हूँ तालिका पंक्तियों की गणना में बहुत धीमी है (मुख्य रूप से TestStack.White
का उपयोग कर एक अनुकूल इंटरफेस प्रदान करने के लिए है, यह एक पीठ के अंत के रूप में System.Windows.Automation
उपयोग करता है) । मेरे पास ~ 200 पंक्तियों वाली एक तालिका है जिसे मुझे मूल्यों का परीक्षण करने की आवश्यकता है (वास्तव में मैं केवल पहली और आखिरी जोड़ी पंक्तियों का परीक्षण करना चाहता हूं)। मैंने पाया है कि COM-interop UIAutomationCore का उपयोग करके, मैं पंक्तियों को एक सेकंड के एक अंश में समझा सकता हूं, लेकिन केवल तभी जब मैं व्हाइट या System.Windows.Automation
का उपयोग नहीं करता हूं। जैसे ही System.Windows.Automation
initializes के रूप में, भविष्य यूआई स्वचालन कार्यों की गणना करने में पंक्तियों धीमी गति से कर रहे हैं:System.Windows.Automation बनाम UIAutomationCore
First COM run: it took 0.04 seconds to get 102 rows!
First System.Windows.Automation run: it took 7.18 seconds to get 102 rows!
Second COM run: it took 7.87 seconds to get 102 rows!
मैं सत्यापित करें कि यह था अपने आवेदन के साथ क्या करना System.Windows.Automation
और नहीं कुछ एक सरल WinForms परीक्षण आवेदन (TableTest.exe
बनाया
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form() { Text = "TableTest", WindowState = FormWindowState.Maximized };
var dgv = new DataGridView() { Name = "DGV", Dock = DockStyle.Fill, AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill };
dgv.Columns.Add("i", "i");
dgv.Columns.Add("2i", "2i");
dgv.Columns.Add("i^2", "i^2");
dgv.Columns.Add("i^i", "i^i");
for (int i = 0; i < 100; ++i)
dgv.Rows.Add(i, i * 2, i * i, Math.Pow(i, i));
form.Controls.Add(dgv);
Application.Run(form);
}
फिर मैंने पहले परीक्षण के लिए एक और टेस्ट ऐप बनाया। यह कंसोल ऐप या WinForms ऐप के रूप में काम करता है। सबसे पहले मैं COM ऑटोमेशन के साथ परीक्षण करता हूं, फिर System.Windows.Automation के साथ, फिर COM ऑटोमेशन के साथ। आप उपरोक्त उद्धृत आउटपुट से देख सकते हैं, पहला ब्लॉक बहुत क्वायर निष्पादित करता है बदसूरत, अगले दो ब्लॉक धीरे-धीरे धीरे-धीरे निष्पादित करते हैं। अगर मैं System.Windows.Automation
ब्लॉक कोड पर टिप्पणी करता हूं तो दोनों COM ब्लॉक जल्दी निष्पादित होते हैं।
using UIA = Interop.UIAutomationCore;
static void Main(string[] args)
{
var process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
var uia = new UIA.CUIAutomation();
var rootCom = uia.GetRootElement();
var windowCom = rootCom.FindFirst(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_NamePropertyId, "TableTest"));
var dgvCom = windowCom.FindFirst(UIA.TreeScope.TreeScope_Descendants, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_AutomationIdPropertyId, "DGV"));
var start = DateTime.Now;
var rowCount = dgvCom.FindAll(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_ControlTypePropertyId, UIA.UIA_ControlTypeIds.UIA_CustomControlTypeId)).Length;
var elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
var root = AutomationElement.RootElement;
var window = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "TableTest"));
var dgv = window.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "DGV"));
start = DateTime.Now;
rowCount = dgv.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)).Count;
elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
process = System.Diagnostics.Process.Start("TableTest.exe");
System.Threading.Thread.Sleep(500);
uia = new UIA.CUIAutomation();
rootCom = uia.GetRootElement();
windowCom = rootCom.FindFirst(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_NamePropertyId, "TableTest"));
dgvCom = windowCom.FindFirst(UIA.TreeScope.TreeScope_Descendants, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_AutomationIdPropertyId, "DGV"));
start = DateTime.Now;
rowCount = dgvCom.FindAll(UIA.TreeScope.TreeScope_Children, uia.CreatePropertyCondition(UIA.UIA_PropertyIds.UIA_ControlTypePropertyId, UIA.UIA_ControlTypeIds.UIA_CustomControlTypeId)).Length;
elapsed = (DateTime.Now - start).TotalSeconds;
Console.WriteLine(String.Format("It took {0} seconds to get {1} rows!", elapsed.ToString("f2"), rowCount));
process.Kill();
}
क्या बिल्ली System.Windows.Automation
कर रही है कि यूआई स्वचालन के प्रदर्शन को मारता है? मैंने व्हाइट सोर्स कोड देखा है और मुझे कुछ भी स्पष्ट नहीं दिख रहा है। मैं System.Windows.Automation प्रोफाइल नहीं कर सकता क्योंकि मुझे इसके लिए कोई पीडीबी नहीं मिल रहा है। मैं यूआई ऑटोमेशन से बहुत परिचित नहीं हूं इसलिए शायद यह किसी और के लिए स्पष्ट होगा। व्हाइट है: 0.13.0.0
और मैं 64-बिट विंडोज 7 पर परीक्षण कर रहा हूं।
मैं अपने उदाहरण पुनर्संशोधित 'उपयोग करने के लिए System.Windows.Automation' और पाया कि समस्या है, व्हाइट में नहीं है (जो' System.Windows.Automation' बल्कि COM इंटरफेस से उपयोग करता है)। अर्थात। 'System.Windows.Automation' का उपयोग करते समय, पहली पंक्ति गणना दूसरी के रूप में धीमी है। शायद यह संकीर्ण चीजों को कम करने में मदद करता है? –
मैंने आपकी समस्या को दोहराया है और यह बहुत अजीब है। मैं समझता हूं कि COM विधि तेज क्यों है क्योंकि यह अप्रबंधित कोड का उपयोग करता है जो पेड़ को और अधिक तेज़ी से पार करेगा। क्यों System.Windows.Automation विधि COM पुस्तकालयों को बाद में कॉल को मारना चाहिए हालांकि मुझे कोई जानकारी नहीं है। मैं सफेद से अपरिचित हूं, लेकिन क्या इस रैपर http://uiacomwrapper.codeplex.com/ के साथ इसका उपयोग करना संभव है? यह आपको COM विधि के प्रदर्शन के साथ व्हाइट प्रदान करता है जो इंटरफ़ेस प्रदान करता है। –
मैंने Winforms-code का कुछ निरीक्षण किया और मुझे लगता है कि कई सारे प्रेषण, peekmessages और प्रतीक्षा शामिल हैं –