基本上,我有一个WPF应用程序,其中用户编写一个进程名称, 然后,一个新的Thread开始,如果进程尚未打开,它将继续进行扫描,直到找到该进程,该线程才会处于活动状态。因此,我可以获取该句柄并编写内存!
private void scanBtn_Click (object sender, RoutedEventArgs e)
{
Thread s = new Thread(( ) => {
this.Dispatcher.Invoke((Action)(( ) =>
{
scanner(pName.Text);
}));
});
try
{
if (pName.Text != string.Empty)
{
InfoTxt.Text = "[ WAITING FOR PROCESS TO OPEN ]";
s.Start();
pName.IsEnabled = false;
if (!s.IsAlive)
{
pName.IsEnabled = true;
InfoTxt.Text = "[ FOUND ]";
Process p = Process.GetProcessesByName(pName.Text)[0];
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private static void scanner ( string procName)
{
while (true)
{
Process s = SeekProcName(procName);
if (s != null) break;
}
}
private static Process SeekProcName(string pName)
{
Process[] procs = Process.GetProcesses().Where(p => p.MainWindowHandle != (IntPtr)0).ToArray();
Process f = null;
foreach (var item in procs)
{
if (item.ProcessName.ToLower() == pName.ToLower())
{
f = item;
break;
}
}
return f;
}
答案 0 :(得分:0)
s
线程正在尝试在UI线程上运行委托,这意味着它与在事件处理程序中直接调用SeekProcName(procName)
没什么不同。
最好使用Task.Run
和async/await
在后台线程中运行检查。返回await
后,将在UI线程中恢复执行,这意味着可以更新UI,而无需Invoke
或BeginInvoke
private async void scanBtn_Click (object sender, RoutedEventArgs e)
{
InfoTxt.Text = "[ WAITING FOR PROCESS TO OPEN ]";
//Read the textbox contets *before* starting the task
var name=pName.Text;
var p=await Task.Run(()=>SeekProcName(name));
if (p!=null)
{
InfoTxt.Text = "[ FOUND ]";
}
}
这可以在循环中调用,迭代之间的延迟很小,而不会阻塞UI线程:
private async void scanBtn_Click (object sender, RoutedEventArgs e)
{
while(someCondition)
{
InfoTxt.Text = "[ WAITING FOR PROCESS TO OPEN ]";
var name=pName.Text;
var p=await Task.Run(()=>SeekProcName(name));
if (p!=null)
{
InfoTxt.Text = "[ FOUND ]";
}
await Task.Delay(1000);
}
}