Если я правильно читаю ваш вопрос - код, который хочет, чтобы синхронный вызов метода асинхронизации выполнялся в приостановленном потоке диспетчера. И вы хотите фактически синхронизировать этот поток до тех пор, пока не будет завершен метод async.
Асинхронные методы на C # 5 приводятся в действие путем эффективного измельчения метода на куски под капотом и возвращения Task
, который может отслеживать общее завершение всего шабанга. Однако, как выполняются методы прерывания, может зависеть от типа выражения, переданного оператору await
.
В большинстве случаев вы будете использовать await
для выражения типа Task
. Выполнение задачи await
шаблона является «умным», поскольку оно отбрасывает SynchronizationContext
, что в основном приводит к следующему:
await
, включен поток потока сообщений диспетчера или WinForms, он гарантирует, что куски асинхронного метода выполняются как часть обработки очереди сообщений. await
, находится в потоке пула потоков, то оставшиеся куски асинхронного метода встречаются в любом месте пула потоков. Вот почему вы, вероятно, сталкиваетесь с проблемами - реализация метода асинхронного тестирования пытается запустить остальные на диспетчере - даже если он приостановлен.
.... резервное копирование! ....
Я должен задать вопрос, , почему вы пытаетесь синхронно блокировать метод async? Это может привести к тому, что метод будет вызван асинхронно. В общем случае, когда вы начинаете использовать await
в методе Dispatcher или UI, вам нужно будет перевернуть весь ваш асинхронный поток пользовательского интерфейса. Например, если ваш столбец был примерно таким:
Затем, как только код был преобразован для использования async, вы, как правило, получите
Фактически Ответ
Класс AsyncHelpers выше работает, потому что он ведет себя как вложенный цикл сообщений, но он устанавливает свой собственный параллельный механизм для диспетчера, вместо того, чтобы пытаться выполнить сам Диспетчер. Это один из способов решения вашей проблемы.
Другим обходным решением является выполнение вашего асинхронного метода в потоке threadpool, а затем дождаться его завершения. Делать это легко - вы можете сделать это со следующим фрагментом:
var customerList = TaskEx.RunEx(GetCustomers).Result;
Конечным API будет Task.Run (...), но с CTP вам понадобятся суффиксы Ex ( здесь ).
На веб-сайте я нажимаю кнопку, которая открывает небольшое подокно
blockquote>Здесь вы упомянули, что открываете новое подокно, в котором нужно нажать кнопка для скачивания. Но вы не переключаетесь на это окно. Следовательно, не в состоянии найти этот элемент.
Используйте
driver.window_handles
, чтобы получить указатель на открытое окно и переключитесь на это окно, используяdriver.switch_to_window()
, затем попробуйте нажать на кнопку, чтобы загрузить.Вы можете увидеть, как обрабатывать несколько окон в python selenium в этом стековом потоке , ссылка .
РЕДАКТИРОВАТЬ:
Так что, похоже, в вашем коде были некоторые проблемы. Как и локатор для кнопок загрузки рядом с шахматной доской и одна после этого были неправильными. Я исправил локатор с помощью правильного
xpath
, а также внес небольшие изменения вchrome_options
. Вам просто нужно изменитьdownload.defualt_directory
на путь в вашем компьютере, и код ниже будет работать:from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_experimental_option("prefs", { "download.default_directory": r"C:\Users\Thanthu Nair\Downloads\Test", "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True }) driver = webdriver.Chrome("./chromedriver", options=chrome_options) website = "https://www.chess.com/ccc" driver.get(website) # loads the page driver.maximize_window() # This closes a sub-window that opens automatically element = driver.find_element_by_class_name("form-button-component") element.click() download = driver.find_element_by_xpath("//i[@title='Download']") download.click() # Click to download download.find_element_by_xpath("//button[normalize-space()='Download Game (PGN)']").click()