问题描述
我正在编写应用程序,此代码部分是不起作用的部分的简化版本...
该应用程序将是使用UIAutomation操作UI的Windows窗体应用程序.
Mainthread和eventhandling线程也可以操纵UI,因此在事件处理期间,我想挂起mainthread以不具有UI的并发用法.
也许使用的方法不是最好的...但是我不知道如何以不同的方式做到这一点.
我的问题是,对于事件处理,我正在使用一个线程,并且当我想在for语句中到达主线程的静态变量时,该线程将挂起.
这个简化的版本设法访问它,但是在迭代过程中挂起,我的实际应用程序在第一次迭代时挂起...
任何帮助将不胜感激...
在此先谢谢您,
B.
I am coding an application and this codepart is the simplified version of the not working part...
The app will be a Windows Form application manipulating UI using UIAutomation.
Mainthread and eventhandling thread manipulates the UI as well so during event handling i want to suspend the mainthread not to have concurrent usage of the UI.
Maybe the used method is not the best...but i have no idea how to do this in different way.
My problem would be that for event handling i am using a thread and this thread hangs when i want to reach mainthread''s static variables in the for statement.
This simplified version manages to access it but hangs during the iteration, my real application hangs for the first iteration...
Any help would be appreciated...
Thanks in advanced,
B.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Automation;
using System.Diagnostics;
using System.Threading;
using Microsoft.Win32;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Net.Mail;
using System.Net;
using System.Net.Mime;
using System.Runtime.InteropServices;
using System.Media;
namespace TestEHWin
{
internal static class Worker
{
internal static AutomationElement eventSenderElement = null;
internal static List<AutomationElement> dialogs = new List<AutomationElement>();
internal static Thread mainThread;
internal static string debugFile = @"C:\Test_logging.txt";
internal static string debugFileEvent = @"C:\Test_logging_Event.txt";
internal static void Start()
{
StreamWriter sw = new StreamWriter(Worker.debugFileEvent);
sw.Close();
int _counter = 0;
mainThread = Thread.CurrentThread;
DebugWrite("M - Mainthread id: " + mainThread.ManagedThreadId);
dialogs = GetChildDialogs(AutomationElement.RootElement);
foreach (AutomationElement _item in dialogs)
{
DebugWrite("M - Dialog: " + _item.Current.Name);
}
Automation.AddStructureChangedEventHandler(AutomationElement.RootElement, TreeScope.Children, new StructureChangedEventHandler(strucChangedHandler));
DateTime stop = DateTime.Now.AddSeconds(20);
do
{
_counter++;
DebugWrite("M - Iteration number #" + _counter.ToString());
Sleep(10);
} while (DateTime.Now < stop);
Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement, strucChangedHandler);
MessageBox.Show("Finished....");
}
private static void strucChangedHandler(object _sender, StructureChangedEventArgs _e)
{
AutomationElement _senderElement = _sender as AutomationElement;
Object _windowPattern;
if (_e.StructureChangeType == StructureChangeType.ChildAdded)
{
if (false == _senderElement.TryGetCurrentPattern(WindowPattern.Pattern, out _windowPattern))
{
return;
}
eventSenderElement = _senderElement;
System.Threading.Thread _thread = new Thread(new ThreadStart(testHandler));
_thread.Priority = ThreadPriority.Highest;
_thread.Start();
}
}
private static void testHandler()
{
mainThread.Suspend();
DebugWriteEvent("EHT - Thread #" + mainThread.ManagedThreadId.ToString() + " will be suspended.");
DebugWriteEvent("EHT - ThreadID: " + Thread.CurrentThread.ManagedThreadId);
DebugWriteEvent("EHT - New dialog name: " + eventSenderElement.Current.Name);
dialogs = GetChildDialogs(AutomationElement.RootElement);
DebugWriteEvent("EHT - Dialogs number: #" + dialogs.Count.ToString());
for (int i = 0; i < dialogs.Count; i++)
{
DebugWriteEvent("EHT - Dialog#" + (i + 1).ToString() + " in root: " + dialogs[i].Current.Name);
Thread.Sleep(100);
}
DebugWriteEvent("EHT - Thread #" + mainThread.ManagedThreadId.ToString() + " will be alive again.");
mainThread.Resume();
}
internal static void Sleep(int timeoutInMs)
{
TimeSpan wait = DateTime.Now.TimeOfDay;
wait = wait.Add(new TimeSpan(0, 0, 0, 0, timeoutInMs));
while (DateTime.Now.TimeOfDay < wait)
{
Application.DoEvents();
}
}
internal static List<AutomationElement> GetChildDialogs(AutomationElement _basedialog)
{
List<AutomationElement> _dialoglist = new List<AutomationElement>();
TreeWalker _walker = new TreeWalker(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
AutomationElement _node = _walker.GetFirstChild(_basedialog);
while (_node != null)
{
_dialoglist.Add(_node);
_node = _walker.GetNextSibling(_node);
}
return _dialoglist;
}
internal static void DebugWrite(string _text)
{
StreamWriter sw = File.AppendText(Worker.debugFile);
sw.WriteLine(DateTime.Now.ToString("HHmmss_fffffff: ") + _text + " Thread ID: " + Thread.CurrentThread.ManagedThreadId.ToString());
sw.Flush();
sw.Close();
return;
}
internal static void DebugWriteEvent(string _text)
{
StreamWriter sw = File.AppendText(Worker.debugFileEvent);
sw.WriteLine(DateTime.Now.ToString("HHmmss_fffffff: ") + _text + " Thread ID: " + Thread.CurrentThread.ManagedThreadId.ToString());
sw.Flush();
sw.Close();
return;
}
}
}
固定代码格式
Fixed code formatting
推荐答案
这篇关于访问主线程变量时线程挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!