Tôi cần đảm bảo rằng một quy trình đang chạy trước khi tiếp tục với một phương thức.
Tuyên bố là:
Process.Start("popup.exe");
Bạn có thể thực hiện lệnh WAIT hoặc đặt độ trễ cho giá trị này không?
Tôi cần đảm bảo rằng một quy trình đang chạy trước khi tiếp tục với một phương thức.
Tuyên bố là:
Process.Start("popup.exe");
Bạn có thể thực hiện lệnh WAIT hoặc đặt độ trễ cho giá trị này không?
Câu trả lời:
Ý bạn là đợi cho đến khi nó hoàn thành? Sau đó sử dụng Process.WaitForExit
:
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "popup.exe"
}
};
process.Start();
process.WaitForExit();
Ngoài ra, nếu đó là một ứng dụng có giao diện người dùng mà bạn đang đợi để nhập vào vòng lặp thông báo, bạn có thể nói:
process.Start();
process.WaitForInputIdle();
Cuối cùng, nếu cả hai đều không áp dụng, chỉ Thread.Sleep
trong một khoảng thời gian hợp lý:
process.Start();
Thread.Sleep(1000); // sleep for one second
process.Start()
trước đó process.WaitForExit()
; nếu không một ngoại lệ sẽ được ném ra.
Tôi cũng cần điều này một lần và tôi đã kiểm tra tiêu đề cửa sổ của quá trình. Nếu đó là ứng dụng bạn mong đợi, bạn có thể chắc chắn rằng ứng dụng đang chạy. Ứng dụng tôi đang kiểm tra cần một thời gian để khởi động và phương pháp này hoạt động tốt đối với tôi.
var process = Process.Start("popup.exe");
while(process.MainWindowTitle != "Title")
{
Thread.Sleep(10);
}
Câu trả lời của 'ChrisG' là đúng, nhưng chúng tôi cần phải làm mới MainWindowTitle mỗi lần và tốt hơn là kiểm tra xem có trống không .... như thế này:
var proc = Process.Start("popup.exe");
while (string.IsNullOrEmpty(proc.MainWindowTitle))
{
System.Threading.Thread.Sleep(100);
proc.Refresh();
}
Trước hết: Tôi biết điều này khá cũ nhưng vẫn chưa có câu trả lời được chấp nhận, vì vậy có lẽ cách tiếp cận của tôi sẽ giúp ích cho người khác. :)
Những gì tôi đã làm để giải quyết vấn đề này là:
process.Start();
while (true)
{
try
{
var time = process.StartTime;
break;
}
catch (Exception) {}
}
Hiệp hội var time = process.StartTime
sẽ ném ra một ngoại lệ miễn là quá trình không bắt đầu. Vì vậy, một khi nó trôi qua, có thể an toàn khi cho rằng tiến trình đang chạy và tiếp tục làm việc với nó. Tôi đang sử dụng cái này để đợi quá trình java khởi động, vì nó mất một khoảng thời gian. Bằng cách này, nó sẽ độc lập trên máy mà ứng dụng đang chạy hơn là sử dụng Thread.Sleep()
.
Tôi hiểu đây không phải là giải pháp sạch cho lắm, nhưng là giải pháp duy nhất độc lập về hiệu suất mà tôi có thể nghĩ ra.
Giống như những người khác đã nói, nó không rõ ràng ngay lập tức những gì bạn đang hỏi. Tôi sẽ giả định rằng bạn muốn bắt đầu một quy trình và sau đó thực hiện một hành động khác khi quy trình "sẵn sàng".
Tất nhiên, "đã sẵn sàng" là một chút khó khăn. Tùy thuộc vào nhu cầu của bạn, bạn có thể thấy rằng chỉ cần chờ đợi là đủ. Tuy nhiên, nếu bạn cần một giải pháp mạnh mẽ hơn, bạn có thể cân nhắc sử dụng Mutex có tên để kiểm soát luồng điều khiển giữa hai quy trình của mình.
Ví dụ: trong quy trình chính của bạn, bạn có thể tạo mutex có tên và bắt đầu một chuỗi hoặc tác vụ sẽ chờ. Sau đó, bạn có thể bắt đầu quá trình thứ hai. Khi quá trình đó quyết định rằng "nó đã sẵn sàng", nó có thể mở mutex được đặt tên (tất nhiên bạn phải sử dụng cùng tên) và báo hiệu cho quá trình đầu tiên.
Tôi đồng ý với Tom. Ngoài ra, để kiểm tra các tiến trình trong khi thực hiện Thread.Sleep, hãy kiểm tra các tiến trình đang chạy. Cái gì đó như:
bool found = 0;
while (!found)
{
foreach (Process clsProcess in Process.GetProcesses())
if (clsProcess.Name == Name)
found = true;
Thread.CurrentThread.Sleep(1000);
}
while (!Process.GetProcesses().Any(p=>p.Name == myName)) { Thread.Sleep(100); }
GetProcessesByName()
? while(Process.GetProcessesByName(myName).Length == 0) { Thread.Sleep(100); }
Trong khi nó có thể làm việc hầu hết phần thời gian, cách thích hợp sẽ chờ đợi cho đến khi n mileseconds và thoát ra khỏi vòng lặp nếu quá trình này đã không được tìm thấy.
Bạn có chắc chắn Start
phương thức trả về trước khi tiến trình con bắt đầu không? Tôi luôn có ấn tượng rằng Start
bắt đầu quá trình trẻ em một cách đồng bộ.
Nếu bạn muốn đợi cho đến khi quy trình con của bạn hoàn thành một số loại khởi tạo thì bạn cần giao tiếp giữa các quy trình - hãy xem Giao tiếp liên quy trình dành cho Windows trong C # (.NET 2.0) .
Để mở rộng ý tưởng của @ ChrisG, hãy xem xét sử dụng process.MainWindowHandle và xem vòng lặp thông báo cửa sổ có phản hồi hay không. Sử dụng p / gọi api Win32 này: SendMessageTimeout . Từ liên kết đó:
Nếu chức năng thành công, giá trị trả về là khác không. SendMessageTimeout không cung cấp thông tin về việc hết thời gian chờ của từng cửa sổ nếu HWND_BROADCAST được sử dụng.
Nếu chức năng bị lỗi hoặc hết thời gian, giá trị trả về là 0. Để nhận thông tin lỗi mở rộng, hãy gọi GetLastError. Nếu GetLastError trả về ERROR_TIMEOUT, thì hàm đã hết thời gian chờ.
Tôi đã sử dụng lớp EventWaitHandle . Trên tiến trình mẹ, hãy tạo EventWaitHandle có tên với trạng thái ban đầu của sự kiện được đặt thành không báo hiệu. Tiến trình mẹ sẽ chặn cho đến khi tiến trình con gọi phương thức Set , thay đổi trạng thái của sự kiện thành signaled, như hình dưới đây.
Quy trình dành cho cha mẹ:
using System;
using System.Threading;
using System.Diagnostics;
namespace MyParentProcess
{
class Program
{
static void Main(string[] args)
{
EventWaitHandle ewh = null;
try
{
ewh = new EventWaitHandle(false, EventResetMode.AutoReset, "CHILD_PROCESS_READY");
Process process = Process.Start("MyChildProcess.exe", Process.GetCurrentProcess().Id.ToString());
if (process != null)
{
if (ewh.WaitOne(10000))
{
// Child process is ready.
}
}
}
catch(Exception exception)
{ }
finally
{
if (ewh != null)
ewh.Close();
}
}
}
}
Tiến trình con:
using System;
using System.Threading;
using System.Diagnostics;
namespace MyChildProcess
{
class Program
{
static void Main(string[] args)
{
try
{
// Representing some time consuming work.
Thread.Sleep(5000);
EventWaitHandle.OpenExisting("CHILD_PROCESS_READY")
.Set();
Process.GetProcessById(Convert.ToInt32(args[0]))
.WaitForExit();
}
catch (Exception exception)
{ }
}
}
}
Đây là một triển khai sử dụng a System.Threading.Timer
. Có thể hơi nhiều cho mục đích của nó.
private static bool StartProcess(string filePath, string processName)
{
if (!File.Exists(filePath))
throw new InvalidOperationException($"Unknown filepath: {(string.IsNullOrEmpty(filePath) ? "EMPTY PATH" : filePath)}");
var isRunning = false;
using (var resetEvent = new ManualResetEvent(false))
{
void Callback(object state)
{
if (!IsProcessActive(processName)) return;
isRunning = true;
// ReSharper disable once AccessToDisposedClosure
resetEvent.Set();
}
using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
{
Process.Start(filePath);
WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
}
}
return isRunning;
}
private static bool StopProcess(string processName)
{
if (!IsProcessActive(processName)) return true;
var isRunning = true;
using (var resetEvent = new ManualResetEvent(false))
{
void Callback(object state)
{
if (IsProcessActive(processName)) return;
isRunning = false;
// ReSharper disable once AccessToDisposedClosure
resetEvent.Set();
}
using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
{
foreach (var process in Process.GetProcessesByName(processName))
process.Kill();
WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
}
}
return isRunning;
}
private static bool IsProcessActive(string processName)
{
return Process.GetProcessesByName(processName).Any();
}
public static class WinApi
{
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static class Windows
{
public const int NORMAL = 1;
public const int HIDE = 0;
public const int RESTORE = 9;
public const int SHOW = 5;
public const int MAXIMIXED = 3;
}
}
Ứng dụng
String process_name = "notepad"
Process process;
process = Process.Start( process_name );
while (!WinApi.ShowWindow(process.MainWindowHandle, WinApi.Windows.NORMAL))
{
Thread.Sleep(100);
process.Refresh();
}
// Done!
// Continue your code here ...
Bạn cũng có thể kiểm tra xem quá trình đã bắt đầu có đáp ứng hay không bằng cách thử một cái gì đó như sau: while (process.resp Tương ứng)