为Adobe Illustrator异步文件等待任务添加超时机制的实现方案
Great question—this is a super common pitfall when waiting on external processes and their output files. The fix boils down to tracking the Illustrator process explicitly and using Task.WhenAny to race your file-wait task against a timeout task. Here's a step-by-step implementation:
Step 1: Capture the Illustrator Process Reference
First, don’t just fire off the Illustrator command and forget it. Start the process and hold onto a reference so you can terminate it if the timeout hits.
// Configure the Illustrator process start details var aiStartInfo = new ProcessStartInfo { FileName = @"C:\Program Files\Adobe\Adobe Illustrator 2024\Support Files\Contents\Windows\Illustrator.exe", Arguments = $"--your-command-flags-here {inputFilePath} -o {result_file_name}", CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true // Optional: Capture error logs for debugging }; // Launch and track the process using var aiProcess = Process.Start(aiStartInfo); if (aiProcess == null) { Console.WriteLine("Failed to launch Adobe Illustrator."); return; }
Step 2: Race File Wait vs. Timeout
Use Task.WhenAny to wait for either your file creation task or a timeout delay. This stops your app from hanging indefinitely if Illustrator crashes or gets stuck.
// Set your timeout duration (adjust based on typical job length—e.g., 5 minutes) var timeout = TimeSpan.FromMinutes(5); // Race the two tasks var fileWaitTask = WhenFileCreated(result_file_name); var timeoutTask = Task.Delay(timeout); var completedTask = await Task.WhenAny(fileWaitTask, timeoutTask);
Step 3: Handle Timeout & Failure Cases
Check which task finished first and take appropriate action:
if (completedTask == timeoutTask) { // Timeout triggered—kill the stuck Illustrator process if (!aiProcess.HasExited) { aiProcess.Kill(); aiProcess.WaitForExit(); // Ensure it’s fully terminated before moving on } Console.WriteLine($"Timeout waiting for {result_file_name}. Illustrator process terminated."); return; // Skip to next job or handle the failure } // If file wait completed, verify both the file exists AND Illustrator exited successfully if (File.Exists(result_file_name) && aiProcess.HasExited && aiProcess.ExitCode == 0) { // Proceed with your post-processing logic here Console.WriteLine("Result file generated successfully."); // ... your code to process the file ... } else { // Illustrator failed or the file is missing/corrupted if (!aiProcess.HasExited) { aiProcess.Kill(); aiProcess.WaitForExit(); } // Grab error output if you enabled it earlier var errorLog = await aiProcess.StandardError.ReadToEndAsync(); Console.WriteLine($"Illustrator failed. Exit code: {aiProcess.ExitCode}. Error: {errorLog}"); // Handle failure (log, retry, or skip) }
Quick Note on WhenFileCreated
If your WhenFileCreated is a custom function, make sure it’s robust. A simple, reliable version might look like this:
public async Task WhenFileCreated(string filePath) { while (!File.Exists(filePath)) { await Task.Delay(1000); // Check for the file every second } }
Key Takeaways
- Always track external processes: This lets you clean up stuck instances instead of leaving them running.
Task.WhenAnyis your friend: It’s the cleanest way to add timeouts to async operations without blocking threads.- Don’t trust just the file: Verify Illustrator exited successfully to avoid processing corrupted or incomplete files.
内容的提问来源于stack exchange,提问作者Donnie Sparko

