Всем привет.
Долго бьюсь, но никак не могу победить и даже не понимаю в чем проблема-то.
Поток зависает на определенном действии, без ошибок, просто C# висит и всё, всё время в одном месте, предположил, что связано с буфером обмена.
А вот класс, в котором идет копирование и вставка из буфера обмена, а потом возврат буфера (смотрел посты Альфреда, оттуда и взял логику)
И ладно бы он хоть что-то выбивал, а так лог висит на "Пробуем вставку через буфер обмена" и всё, если посмотреть глазами - скрипт просто смотрит в окно ввода и всё. Окно неизменно, он 100% его находит. И отловить закономерность, когда появляется проблема не удалось, т.к. достаточно перезапустить программу и всё будет норм, иногда на пару минут, иногда на пару часов, иногда на целый день.
Помогите плз понять, хотя бы вектор
Долго бьюсь, но никак не могу победить и даже не понимаю в чем проблема-то.
Поток зависает на определенном действии, без ошибок, просто C# висит и всё, всё время в одном месте, предположил, что связано с буфером обмена.
Фрагмент экшена, где случается зависание:
project.SendInfoToLog("Пробуем вставку через буфер обмена", true);
try
{
// Выполняем вставку
bool success = ZennoLab.OwnCode.CommonCode.ClipboardTools.SafePasteText(instance, project, domains);
project.SendInfoToLog("Вставил домены из буфера обмена", true);
if(!success)
{
project.SendErrorToLog("Не удалось вставить домены", true);
throw new Exception("Не смог вставить домены");
}
project.SendInfoToLog("Буфер обмена - всё окей", true);
return "OK";
}
catch (Exception ex)
{
project.SendInfoToLog($"Буфер обмена ошибка: {ex.Message}", true);
// Если было много доменов и буфер не сработал - пробуем построчную вставку
if (domainCount >= 5)
{
project.SendInfoToLog("Буфер обмена не сработал, пробуем построчную вставку как fallback", true);
try
{
targetElement.Click();
System.Threading.Thread.Sleep(100);
// Вставляем построчно с Enter между ними
for (int i = 0; i < domainLines.Length; i++)
{
string domain = domainLines[i].Trim();
if (!string.IsNullOrEmpty(domain))
{
instance.SendText(domain, 0);
if (i < domainLines.Length - 1)
{
instance.SendText("{ENTER}", 0);
}
}
}
project.SendInfoToLog("Fallback построчная вставка выполнена", true);
return "OK";
}
catch (Exception ex2)
{
project.SendInfoToLog($"Fallback построчная вставка ошибка: {ex2.Message}", true);
}
}
}
Код:
public static class ClipboardTools
{
private const int MAX_CLIPBOARD_RETRIES = 3;
private const int CLIPBOARD_DELAY = 100;
private const int PASTE_DELAY = 200;
public static bool SafePasteText(Instance instance, IZennoPosterProjectModel project, string text)
{
lock(SyncObjects.InputSyncer)
{
try
{
// Проверяем входной текст
if (string.IsNullOrEmpty(text))
{
project.SendWarningToLog("Текст для вставки пуст", true);
return false;
}
var textbox = instance.ActiveTab.FindElementByXPath("//div[@role = 'textbox']", 0);
if(textbox.IsNull)
{
project.SendWarningToLog("Не найдено текстовое поле", true);
return false;
}
// Сохраняем предыдущее состояние буфера с повторами
string previousText = GetClipboardTextSafely(project);
try
{
// Подготавливаем элемент для ввода
textbox.Click();
Thread.Sleep(50);
// Устанавливаем текст в буфер с повторами
bool clipboardSet = SetClipboardTextSafely(text, project);
if (!clipboardSet)
{
project.SendErrorToLog("Не удалось установить текст в буфер обмена", true);
return false;
}
// Выполняем вставку с проверкой
bool pasteSuccess = ExecutePasteSafely(instance, project);
if (!pasteSuccess)
{
project.SendErrorToLog("Не удалось выполнить вставку", true);
return false;
}
Thread.Sleep(PASTE_DELAY);
return true;
}
finally
{
// Восстанавливаем предыдущее состояние буфера
RestoreClipboardSafely(previousText, project);
}
}
catch (Exception ex)
{
project.SendErrorToLog($"Критическая ошибка при вставке текста: {ex.Message}", true);
return false;
}
}
}
private static string GetClipboardTextSafely(IZennoPosterProjectModel project)
{
for (int attempt = 1; attempt <= MAX_CLIPBOARD_RETRIES; attempt++)
{
try
{
if (System.Windows.Forms.Clipboard.ContainsText())
{
return System.Windows.Forms.Clipboard.GetText();
}
return string.Empty;
}
catch (Exception ex)
{
project.SendWarningToLog($"Попытка {attempt} получения буфера неудачна: {ex.Message}", false);
if (attempt < MAX_CLIPBOARD_RETRIES)
{
Thread.Sleep(CLIPBOARD_DELAY);
}
}
}
project.SendWarningToLog("Не удалось получить содержимое буфера после всех попыток", false);
return string.Empty;
}
private static bool SetClipboardTextSafely(string text, IZennoPosterProjectModel project)
{
for (int attempt = 1; attempt <= MAX_CLIPBOARD_RETRIES; attempt++)
{
try
{
// Сначала очищаем буфер
System.Windows.Forms.Clipboard.Clear();
Thread.Sleep(50);
// Устанавливаем новый текст
System.Windows.Forms.Clipboard.SetText(text, System.Windows.Forms.TextDataFormat.UnicodeText);
Thread.Sleep(CLIPBOARD_DELAY);
// Проверяем, что текст действительно установлен
string clipboardContent = System.Windows.Forms.Clipboard.GetText();
if (clipboardContent == text)
{
return true;
}
else
{
project.SendWarningToLog($"Попытка {attempt}: текст в буфере не соответствует ожидаемому", false);
}
}
catch (Exception ex)
{
project.SendWarningToLog($"Попытка {attempt} установки буфера неудачна: {ex.Message}", false);
}
if (attempt < MAX_CLIPBOARD_RETRIES)
{
Thread.Sleep(CLIPBOARD_DELAY);
}
}
return false;
}
private static bool ExecutePasteSafely(Instance instance, IZennoPosterProjectModel project)
{
for (int attempt = 1; attempt <= MAX_CLIPBOARD_RETRIES; attempt++)
{
try
{
// Выполняем вставку
instance.ActiveTab.KeyEvent("v", "press", "ctrl");
Thread.Sleep(PASTE_DELAY);
// Можно добавить дополнительную проверку успешности вставки
// например, проверить изменилось ли содержимое поля
return true;
}
catch (Exception ex)
{
project.SendWarningToLog($"Попытка {attempt} вставки неудачна: {ex.Message}", false);
if (attempt < MAX_CLIPBOARD_RETRIES)
{
Thread.Sleep(CLIPBOARD_DELAY);
}
}
}
return false;
}
private static void RestoreClipboardSafely(string previousText, IZennoPosterProjectModel project)
{
for (int attempt = 1; attempt <= MAX_CLIPBOARD_RETRIES; attempt++)
{
try
{
System.Windows.Forms.Clipboard.Clear();
Thread.Sleep(50);
if (!string.IsNullOrEmpty(previousText))
{
System.Windows.Forms.Clipboard.SetText(previousText, System.Windows.Forms.TextDataFormat.UnicodeText);
}
break; // Если успешно - выходим
}
catch (Exception ex)
{
project.SendWarningToLog($"Попытка {attempt} восстановления буфера неудачна: {ex.Message}", false);
if (attempt < MAX_CLIPBOARD_RETRIES)
{
Thread.Sleep(CLIPBOARD_DELAY);
}
}
}
}
// Дополнительная функция для проверки состояния буфера
public static bool IsClipboardReady()
{
try
{
return System.Windows.Forms.Clipboard.ContainsText() ||
System.Windows.Forms.Clipboard.ContainsData(System.Windows.Forms.DataFormats.Text);
}
catch
{
return false;
}
}
}
Помогите плз понять, хотя бы вектор
