2015-02-05 8 views
7

मैं यूआई स्वचालन के माध्यम से अपने आवेदन के स्वचालित परीक्षण करने की कोशिश कर रहा हूँ तालिका पंक्तियों की गणना में बहुत धीमी है (मुख्य रूप से 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 पर परीक्षण कर रहा हूं।

+0

मैं अपने उदाहरण पुनर्संशोधित 'उपयोग करने के लिए System.Windows.Automation' और पाया कि समस्या है, व्हाइट में नहीं है (जो' System.Windows.Automation' बल्कि COM इंटरफेस से उपयोग करता है)। अर्थात। 'System.Windows.Automation' का उपयोग करते समय, पहली पंक्ति गणना दूसरी के रूप में धीमी है। शायद यह संकीर्ण चीजों को कम करने में मदद करता है? –

+0

मैंने आपकी समस्या को दोहराया है और यह बहुत अजीब है। मैं समझता हूं कि COM विधि तेज क्यों है क्योंकि यह अप्रबंधित कोड का उपयोग करता है जो पेड़ को और अधिक तेज़ी से पार करेगा। क्यों System.Windows.Automation विधि COM पुस्तकालयों को बाद में कॉल को मारना चाहिए हालांकि मुझे कोई जानकारी नहीं है। मैं सफेद से अपरिचित हूं, लेकिन क्या इस रैपर http://uiacomwrapper.codeplex.com/ के साथ इसका उपयोग करना संभव है? यह आपको COM विधि के प्रदर्शन के साथ व्हाइट प्रदान करता है जो इंटरफ़ेस प्रदान करता है। –

+0

मैंने Winforms-code का कुछ निरीक्षण किया और मुझे लगता है कि कई सारे प्रेषण, peekmessages और प्रतीक्षा शामिल हैं –

उत्तर

0

आपके द्वारा पोस्ट किए गए उदाहरण व्हाइट का उपयोग नहीं करते हैं ... FWIW, व्हाइट ऑटोमेशन के लिए रिकर्सिव कॉल का उपयोग करता है। हर बार बच्चों से अनुरोध करने के लिए। यह वैध परिणाम देता है लेकिन उपयुक्त पैरेंट नोड से उपट्री का अनुरोध करने से धीमा है - ध्यान दें कि रूट नोड कभी भी 'उचित' नोड नहीं है जिससे उपट्री का अनुरोध किया जा सके (MSDN पर नोट देखें)। चूंकि आपका उदाहरण केवल बच्चों को एक बार अनुरोध करता है, यह मुद्दा नहीं है।

2

मैं आपके प्रश्न का उत्तर नहीं दे सकता। लेकिन बहुत से लोग Google से यहां आएंगे जो "यूआईयूटोमेशन धीमा" कीवर्ड खोजते हैं और Google में पहला परिणाम आपका प्रश्न है। (आपने बेस्टसेलर लिखा है)

Google से आने वाले सभी लोगों के लिए और धीमी यूआईयूयूटीमेशन के साथ संघर्ष करने के लिए मैं यह उत्तर पोस्ट करता हूं।

सिस्टम.Windows.Automation बेहद धीमा है। 30 बच्चे तत्व प्राप्त करना बहुत तेज़ कंप्यूटर पर 1000ms ले सकता है! मैंने यह भी देखा है कि एक क्यूटी आवेदन में एक पेड़ के बच्चे तत्व प्राप्त करते समय हमेशा के लिए लटक रहा है।

इसके अलावा कार्यान्वयन भी धागा सुरक्षित है।

सिस्टम.Windows.Automation बहिष्कृत है। इसका प्रयोग न करें!

में MSDN आप निम्नलिखित टिप्पणी पाते हैं:

यूआई स्वचालन माइक्रोसॉफ्ट .NET फ्रेमवर्क के हिस्से के रूप में Windows XP में पहले से उपलब्ध था।हालांकि उस समय प्रकाशित एक अप्रबंधित सी ++ एपीआई भी था, लेकिन इंटरऑपरेबिलिटी मुद्दों के कारण क्लाइंट फ़ंक्शंस की उपयोगिता सीमित थी। विंडोज 7 के लिए, एपीआई घटक ऑब्जेक्ट मॉडल (COM) में पुनः लिखा गया रहा है। हालांकि लाइब्रेरी फ़ंक्शंस के पुराने संस्करण में पेश किए गए हैं, फिर भी यूआई ऑटोमेशन अभी भी प्रलेखित हैं, उन्हें नए अनुप्रयोगों में उपयोग नहीं किया जाना चाहिए।

प्रदर्शन धीमा करने के लिए समाधान वर्ष System.Windows.Automation सी # इंटरफेस के बजाय नई IUIAutomationElement COM इंटरफ़ेस का उपयोग करने के लिए है। उसके बाद कोड बिजली चल रहा है!

इसके अलावा नया इंटरफ़ेस अधिक पैटर्न प्रदान करता है और माइक्रोसॉफ्ट लगातार इसे विस्तारित कर रहा है। विंडोज 10 एसडीके (UIAutomationClient.h और UIAutomationCore.h) में कई पैटर्न और गुण जोड़े गए हैं जो .NET ऑटोमेशन फ्रेमवर्क में उपलब्ध नहीं हैं।

  • IUIAutomationLegacyIAccessiblePattern
  • IUIAutomationObjectModelPattern
  • IUIAutomationAnnotationPattern
  • IUIAutomationTextPattern2
  • IUIAutomationStylesPattern
  • :

    निम्नलिखित पैटर्न UIAutomation की COM संस्करण है जो System.Windows.Automation में मौजूद नहीं है में उपलब्ध हैं

  • IUIAutomationSpreadsheetPattern
  • IUIAutomationSpreadsheetItemPattern
  • IUIAutomationTransformPattern2
  • IUIAutomationTextChildPattern
  • IUIAutomationDragPattern
  • IUIAutomationDropTargetPattern
  • IUIAutomationTextEditPattern
  • IUIAutomationCustomNavigationPattern

इसके अतिरिक्त निम्नलिखित नियंत्रण प्रकार जोड़ा गया है:

  • AppBar
  • SemanticZoom

इसके अतिरिक्त निम्नलिखित तत्व का जोड़ा गया है:

  • IUIAutomationElement2
  • IUIAutomationElement3
  • IUIAuto mationElement4
+0

आपने बेस्टसेलर सर लिखा था! – Fals

संबंधित मुद्दे