Isolating Clipboard Across Multiple Threads to Avoid Data Mixing?

Pierre Paul Jacques

Активный пользователь
Регистрация
08.10.2023
Сообщения
134
Благодарностей
35
Баллы
28
Hello everyone,

How to Isolating Clipboard Across Multiple Threads to Avoid Data Mixing?

In my template, I often preferring the clipboard for certain actions to save time, such as copying and pasting text directly, rather than emulating keyboard inputs or using project variables.

However, I've encountered a challenge when running multiple threads simultaneously.
Since Windows operates with a single clipboard, this results in an overlap where threads can inadvertently access or overwrite each other's clipboard content, leading to errors and inconsistencies in my automation processes.

Given the nature of my work, switching entirely from clipboard usage to variables isn't always the most efficient solution for me. I'm reaching out to see if anyone has found a way to effectively isolate the clipboard for each thread within ZennoPoster, or if there are any alternative methods to prevent the intermingling of clipboard contents across threads?


Thank you in advance for your help and suggestions!


Exemple of simple code :


C#:
System.Windows.Forms.Clipboard.SetText(project.Variables["C_KeyWord"].Value);

instance.WaitFieldEmulationDelay();
// Emulate text entering
instance.SendText("{CTRLDOWN}v{CTRLUP}", 15);
 

Pierre Paul Jacques

Активный пользователь
Регистрация
08.10.2023
Сообщения
134
Благодарностей
35
Баллы
28
Update this code is maybe a beginning solution?
at least i don't have error of compiling but this i code is also the best exemple because my trouble is some other of my templace where there is 1 to 3 second before the paste...
So another thread can take the"last position" of clipboard...

I am going to sleep, in my dream i hope to find the best solution,)


C#:
lock(SyncObjects.InputSyncer) // Lock to ensure single thread access to the clipboard
{
    // Save current clipboard content to restore later
    var previousClipboardContent = System.Windows.Forms.Clipboard.GetText();

    try
    {
        // Set the content from your variable 'C_KeyWord' to the clipboard
        System.Windows.Forms.Clipboard.SetText(project.Variables["C_KeyWord"].Value);

        // Wait for the field emulation delay configured in your instance
        instance.WaitFieldEmulationDelay();

        // Emulate text entering with the CTRL+V command
        instance.SendText("{CTRLDOWN}v{CTRLUP}", 15);
    }
    finally
    {
        // Restore the previous clipboard content to ensure the clipboard's original state is maintained
        System.Windows.Forms.Clipboard.SetText(previousClipboardContent);
    }
}
 
  • Спасибо
Реакции: morpheus93

Pierre Paul Jacques

Активный пользователь
Регистрация
08.10.2023
Сообщения
134
Благодарностей
35
Баллы
28
Sundays are for Rest, so it's Zenno:bo:

Using the clipboard in Automation is to be avoided, but in some cases I use it because:
  1. Text emulation takes too long (if I set it to fast mode, the text is not recognized/the text area is not activated).
  2. For SEO purposes where I cannot send HTML/markdown code as a guest.
To avoid conflicts in the multithreaded use of the Clipboard, I use: lock(SyncObjects.InputSyncer), but this only works during the execution of the C# block.
However, in some cases, I perform copy-paste operations that have multiple blocks between them that are not custom C# (and that I cannot/want to convert). So for now, I'm using a simple solution: an external file that acts as a "Lock" with a boolean choice managing access to the clipboard! The goal is to ensure that when an element is copied to the clipboard, it is not another thread that pastes it because there is a delay of several seconds between the blocks and there can be interleaving.
I have created the code below, what do you think of the method used?
Was there a simpler/more robust way?

C#:
// Lock : True

// Build the file path
var lockFilePath = Path.Combine(project.Directory, "01 - The Base\\01 - Cookies\\The Lock.txt");
// Check if the clipboard is available
if (File.ReadAllText(lockFilePath) == "False")
{
// The clipboard is available, write "True" to lock it
File.WriteAllText(lockFilePath, "True");
}
else
{
// Wait until the clipboard is available
while (File.ReadAllText(lockFilePath) != "False")
{
// Wait for 1 second before retrying
Thread.Sleep(1000);
}
// Once the clipboard is available, write "True" to lock it
File.WriteAllText(lockFilePath, "True");
}

Then at the end of the process, we write "False" to the text file.

Thank you in advance for your advice!

119040
 

myndeswx

Client
Регистрация
15.05.2017
Сообщения
436
Благодарностей
104
Баллы
43
Seems like you're overcomplicating it a bit, this is what I would suggest you to do if you really want to use the clipboard and not setting it to variable:

Simply create a global variable - these variables are shared between threads.
So the default value would be false, before copying something to the clipboard you check if global variable 'clipboardInUse' is false, if it is in use - you pause for a second and keep checking until clipboard is free to use.
If it is not in use - you copy to clipboard and set 'clipboardInUse' = true, after pasting it - set it back to false, so other threads can start using the clipboard as well. :bt:
119078
 
  • Спасибо
Реакции: Pierre Paul Jacques

Pierre Paul Jacques

Активный пользователь
Регистрация
08.10.2023
Сообщения
134
Благодарностей
35
Баллы
28
Thank a lot!
Mea Culp i never used the "Global Variable" ( in facti I did't know about it),
so Yes your solution is a lot simplier i will implement it!

It was what i i like with Zenno even if found a solution/way for an action there is always to optimise it after and the "fun" is not only to get the result but the journey/path to develop it!
@myndeswx , your help means a lot to me! It's going to kickstart my week on a positive note!


Off Topic, The template you created :
is amazing!
 
  • Спасибо
Реакции: myndeswx

Кто просматривает тему: (Всего: 2, Пользователи: 0, Гости: 2)