Как удалить обработчик событий FileTransferred из объекта сеанса WinSCP?

Я сделал небольшой скрипт-оболочку PowerShell для модуля WinSCP, который соответствует моим потребностям. Как и в примере для синхронизации локальных и удаленных папок, в моем журнале используется событие передачи файла сеансовые события.

$fileTransferedEvent = {Receive-FileTransferredEvent $_}
$session.add_FileTransferred($fileTransferedEvent)

В примере сеанс удаляется после его завершения. Моя логика держит сеанс открытым до тех пор, пока я не решу закончить с ним, чтобы я мог использовать тот же сеанс в другом вызове командлета.

Это создает проблему, если другие командлеты (или даже повторный вызов одного и того же) также используют add_FileTransferred(). Событие добавляется снова, что приводит к X-кратному выходу, где X - это количество вызовов метода.

Я нашел партнерский метод под названием remove_FileTransferred(), но не знаю, как его использовать

Name                   MemberType Definition                                                           
----                   ---------- ----------                                                           
add_FileTransferred    Method     void add_FileTransferred(WinSCP.FileTransferredEventHandler value)   
remove_FileTransferred Method     void remove_FileTransferred(WinSCP.FileTransferredEventHandler value)

Они оба принимают одни и те же значения, поэтому я подумал, что, может быть, я мог бы передать ему определение обработчика, но это, похоже, не работает, т.е. $session.remove_FileTransferred($fileTransferedEvent) не выполнил задание. Тоже не ошибается.

Как удалить обработчики событий передачи файлов для Winscp.Session объектов?


person Matt    schedule 01.06.2017    source источник


Ответы (1)


Это работает для меня отлично:

$fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
$session.add_FileTransferred($fileTransferedEvent)
$session.PutFiles("C:\test.txt", "/").Check()
$session.remove_FileTransferred($fileTransferedEvent)
$session.PutFiles("C:\test.txt", "/").Check()

Я получил:

Upload of C:\test.txt succeeded

Хотя, если я не вызываю remove_FileTransferred, я получаю вывод дважды, как и ожидалось:

Upload of C:\test.txt succeeded
Upload of C:\test.txt succeeded

См. обработчики событий в PowerShell.


Если вы добавите один и тот же обработчик событий несколько раз, обработчик будет вызываться столько раз каждый раз, когда возникает событие. Если вы хотите отменить подписку на событие, вы должны удалить обработчик такое же количество раз. Удаление обработчика, который не добавлен (или уже не добавлен), — это noop. Все это общие правила, не ограничивающиеся сборкой Session.FileTransferred или WinSCP .NET.

Пример:

$fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
$session.add_FileTransferred($fileTransferedEvent)
$session.add_FileTransferred($fileTransferedEvent)

Write-Host "two handlers:"
$session.PutFiles("C:\test.txt", "/").Check()

$session.remove_FileTransferred($fileTransferedEvent)
Write-Host "one handler:"
$session.PutFiles("C:\test.txt", "/").Check()

$session.remove_FileTransferred($fileTransferedEvent)
Write-Host "zero handlers:"
$session.PutFiles("C:\test.txt", "/").Check()

Write-Host "done"

Это даст вам:

two handlers:
Upload of C:\test.txt succeeded
Upload of C:\test.txt succeeded
one handler:
Upload of C:\test.txt succeeded
zero handlers:
done

Хотя, что может быть неочевидным, так это то, что следующие два фрагмента кода не идентичны:

$fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
$session.add_FileTransferred($fileTransferedEvent)
$fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
$session.add_FileTransferred($fileTransferedEvent)
$fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
$session.add_FileTransferred($fileTransferedEvent)
$session.add_FileTransferred($fileTransferedEvent)

Первый фрагмент добавляет два различных обработчика событий, а второй добавляет два идентичных обработчика.

После первого фрагмента вы не можете удалить две регистрации, вызвав это:

$session.remove_FileTransferred($fileTransferedEvent)
$session.remove_FileTransferred($fileTransferedEvent)

Первое «удаление» удалит последний/второй добавленный обработчик. Второе «удаление» ничего не сделает, так как попытается удалить тот же обработчик, который уже был отменен. Поскольку у вас нет ссылки на первый обработчик, вы больше не можете его отменить.

person Martin Prikryl    schedule 01.06.2017
comment
Вот и все. Я сделал функцию, в которой был определен обработчик. сеанс передается, и каждый раз добавляется новый обработчик. Это именно то, что я хотел. Спасибо. Я осиротел обработчиков. - person Matt; 02.06.2017