C# console app copying whole directory and free google translate hangs on first file

Gennady Gurin 231 Reputation points
2026-10-28T23:48:41.3833333+00:00

Hi, I have in my directory some RTF files which I want to translate to a desired language and later append to the same file and continue to the next. It supposed to detect original language (auto). Each file about a page of RTF text.

Here code:


using GoogleTranslateFreeApi;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;

 static async Task Main(string[] args)
 {
string folderPath = @"C:\MY_ORIGINAL_PATH";
string targetLanguageCode = "es"; // Example: "es" for Spanish, "fr" for French, etc.

if (!Directory.Exists(folderPath))
{
    Console.WriteLine("Target directory does not exist.");
    return;
}

// 2. Initialize the Free Google Translator
var translator = new GoogleTranslator();
Language fromLang = Language.Auto;
Language toLang = GoogleTranslator.GetLanguageByISO(targetLanguageCode);

// 3. Process all RTF files in the folder
string[] rtfFiles = Directory.GetFiles(folderPath, "*.rtf");
Console.WriteLine($"Found {rtfFiles.Length} RTF files. Starting translation...");

foreach (string filePath in rtfFiles)
{    
    try
    {
        Console.WriteLine($"Processing: {Path.GetFileName(filePath)}");

        // Using RichTextBox container to safely parse out the RTF syntax
        using (RichTextBox rtb = new RichTextBox())
        {
            // Load the existing RTF file
            string rawRtf = await File.ReadAllTextAsync(filePath);
            rtb.Rtf = rawRtf;

            // Extract pure text for translation (avoids sending RTF code tags to Google)
            string originalPlainText = rtb.Text;

            if (string.IsNullOrWhiteSpace(originalPlainText))
            {
                Console.WriteLine($"Skipping empty file: {Path.GetFileName(filePath)}");
                continue;
            }
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            await Task.Delay(200);
            // Request free translation from Google
            try {
                        
                Task<TranslationResult> translationTask = translator.TranslateLiteAsync(originalPlainText, fromLang, toLang);
                        
                TranslationResult result = await translationTask.WaitAsync(cts.Token);

                string translatedText = result.MergedTranslation;

                Console.WriteLine("Translation completed successfully!");

                // Append translation layout cleanly onto the RichTextBox stream
                rtb.AppendText("\n\nSpanish:\n\n");
                rtb.AppendText(translatedText);
                // Save the updated RTF document back to the original file
                await File.WriteAllTextAsync(filePath, rtb.Rtf);
                Console.WriteLine($"Successfully updated: {Path.GetFileName(filePath)}");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Translation timed out on this file. Skipping or retrying...");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error translating: {ex.Message}");
            }

                    
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error processing file {Path.GetFileName(filePath)}: {ex.Message}");
    }
}


What happens is says:" Processing file1" and it is stuck??

Can anyone tell me what to do next?

Thanks in advance

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

2 answers

Sort by: Most helpful
  1. Harry Nguyen (WICLOUD CORPORATION) 445 Reputation points Microsoft External Staff Moderator
    2026-10-29T06:39:56.9033333+00:00

    Hi @Gennady Gurin ,

    Thank you for sharing the code.

    I performed additional debugging and was able to narrow down where execution stops. The application successfully reaches the translation call:

    Task<TranslationResult> translationTask = translator.TranslateLiteAsync( 
    originalPlainText, 
    fromLang, 
    toLang); 
    

    When inspecting the returned object in the debugger, the method returns a Task with the following state:

    Status = WaitingForActivation 
    Method = <TranslateLiteAsync>d__24 
    

    This indicates that the call itself is not blocking synchronously and that a translation task has been created successfully.

    Execution then waits at:

    TranslationResult result = await translationTask.WaitAsync(cts.Token); 
    

    and does not reach the subsequent statement:

    Console.WriteLine("Translation completed successfully!"); 
    

    Based on these observations, the file-reading and RTF-processing portions of the application appear to be functioning correctly. The code successfully reaches the translation stage, but the translation operation does not complete during execution.

    To further isolate the behavior, I would recommend testing the translator separately using a simple hardcoded string. If the same behavior can be reproduced, it would suggest that the issue is independent of the RTF files and is occurring within the translation layer or its interaction with the translation service.

    As GoogleTranslateFreeApi is a third-party package, our investigation is limited to the behavior visible from the application side. While we can confirm that the translation task is created successfully, we are unable to verify the library's internal implementation or diagnose its communication with the underlying translation service.

    If the behavior persists in a minimal test, you may want to consider evaluating a more actively maintained translation solution, such as an official translation API or another library that is currently supported and updated. This can help determine whether the behavior is specific to the current package and may also provide improved reliability and compatibility over time.

    If the behavior can be reproduced consistently, testing an alternative maintained translation library or service may help determine whether the issue is specific to the current package.

    If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation

    Thank you.

    Was this answer helpful?

    1 person found this answer helpful.

  2. AI answer

    2026-10-28T23:49:50.67+00:00

    Replace GoogleTranslateFreeApi with a maintained translation API; its TranslateLiteAsync implementation has known upstream breakage and may block before returning a Task, so your current WaitAsync is not guaranteed to be reached.^1^^2^

    The supported replacement is an official client such as Google.Cloud.Translate.V3; it requires configuring the Google Cloud Translation service, credentials, and billing.^3^

    Confirm where execution stops

    Your only message is printed before file loading, RTF parsing, and translation. Add checkpoints first:

    Console.WriteLine("1: Reading file");
    string rawRtf = await File.ReadAllTextAsync(filePath);
    
    Console.WriteLine("2: Parsing RTF");
    rtb.Rtf = rawRtf;
    string originalPlainText = rtb.Text;
    
    Console.WriteLine($"3: Calling translator ({originalPlainText.Length} chars)");
    Task<TranslationResult> task =
        translator.TranslateLiteAsync(originalPlainText, fromLang, toLang);
    
    Console.WriteLine("4: Translator returned a Task");
    TranslationResult result =
        await task.WaitAsync(TimeSpan.FromSeconds(10));
    
    Console.WriteLine("5: Translation completed");
    

    Interpret the last message:

    • Stops after 1: file reading is blocked, possibly by file access or storage.
    • Stops after 2: the RTF control is the boundary to investigate.
    • Stops after 3 but never prints 4: TranslateLiteAsync is blocking synchronously before returning its task. No timeout applied afterward can interrupt that call.
    • Prints 4 and then times out: the asynchronous translation request is not completing.

    WaitAsync(TimeSpan) faults with TimeoutException when its timeout expires.^4^ Therefore catch the matching exception:

    try
    {
        TranslationResult result = await translator
            .TranslateLiteAsync(originalPlainText, fromLang, toLang)
            .WaitAsync(TimeSpan.FromSeconds(10));
    }
    catch (TimeoutException)
    {
        Console.WriteLine("Translation exceeded 10 seconds.");
    }
    

    Your existing cancellation-token overload produces OperationCanceledException, but only after execution has reached WaitAsync. It cannot protect against a synchronous stall while TranslateLiteAsync(...) is being invoked.

    Temporary containment for the obsolete library

    If replacement cannot happen immediately, move the entire invocation onto a worker thread so a synchronous stall does not stop the directory loop:

    try
    {
        TranslationResult result = await Task.Run(() =>
            translator.TranslateLiteAsync(originalPlainText, fromLang, toLang))
            .Unwrap()
            .WaitAsync(TimeSpan.FromSeconds(15));
    
        string translatedText = result.MergedTranslation;
    }
    catch (TimeoutException)
    {
        Console.WriteLine("Translator stalled; skipping this file.");
    }
    

    This only abandons waiting. It does not cancel the underlying request or terminate a blocked worker thread, so repeated failures could consume thread-pool threads. Treat it as diagnostic or short-term containment, not a production fix.

    Keep RichTextBox work on an STA thread

    A console application does not install a UI SynchronizationContext; after an await, continuation code normally runs on a thread-pool thread.^5^ RichTextBox is a Windows Forms control, and Windows Forms uses the single-threaded apartment model.^6^

    Adding [STAThread] to an async Main does not ensure that code after each await returns to the original thread. Either:

    • move RTF load/extract/append/save operations to a dedicated STA thread, or
    • remove RichTextBox from the console processing path and use an RTF parser designed for non-UI/background use.

    For synchronous STA processing, RichTextBox.LoadFile and SaveFile are preferable to manually reading and writing its Rtf property. LoadFile replaces the control contents and supports RTF directly.^7^

    Also write to a temporary output file and replace the original only after translation and RTF serialization succeed. That prevents a failed translation or process termination from corrupting the source document.


    References

    1. GitHub - Grizley56/GoogleTranslateFreeApi: Api for free text ...
    2. TranslateLiteAsync Error · Issue #19 · Grizley56/GoogleTranslateFreeApi
    3. Google.Cloud.Translate.V3 | .NET client libraries | Google Cloud ...
    4. Task<TResult>.WaitAsync Method-Definition
    5. SynchronizationContext and console apps
    6. Managed Library Threading Considerations
    7. RichTextBox.LoadFile Method-Definition
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.