2011-03-23 2 views
3

내 프로그램 (.NET 4.0)은 타사 SSH 라이브러리 (SSH.NET, 지금까지 훌륭하게 작동)를 사용하여 UI에서 사용자의 선택에 따라 생성 된 unix 명령을 보내고 respose를 기다리고 출력합니다. 내 문제는 때로는 유닉스 응답이 더 나은 용어가 없어서 "정지"하는 경우에 발생하며,이 경우 내 프로그램이 대기 상태에 머물러있다. 유닉스에서는 그 명령 (CTRL-C의 경우)에서 벗어나 다시 시도 할 수 있지만 라이브러리를 사용할 때 equivelent를 제공하는 방법을 모르겠습니다.C#의 동기식 응용 프로그램에서 UI를 통해 유닉스 호출을 취소하는 가장 좋은 방법은 (SSH 라이브러리 사용)?

또 다른 문제는 UI 스레드가 잠겨있을 때 잠겨 있으므로 "취소"버튼이 있어도 사용자가 클릭 할 수 없다는 것입니다. BackgroundWorker와 Threading을 들여다 보았습니다.하지만 내 작업이 동기 적이기 때문에 실제로 이해가되지 않습니다. 프로그램은 응답 (형식, 색 등)을 분석 할 수 있도록 응답을 기다려야합니다.

이 문제에 대한 의견은 많은 도움이 될 것입니다. 모두 감사합니다.

+0

.net의 버전은 무엇입니까? – CodingGorilla

+0

.NET 4.0, 죄송합니다. – Hershizer33

답변

2

SSH.NET과 그 라이브러리를 통해 명령을 취소 할 수있는 방법을 구체적으로 말할 수는 없지만 접근 방법은 다음과 같습니다.

본질적으로 별도의 스레드 인 Task에서 "명령"을 실행할 것입니다. 여기 내 예제 코드입니다 :

private Task _commandTask; 
private CancellationTokenSource _cancellation; 

protected void SendCommand(object sender, EventArgs e) 
{ 
    if(_commandTask != null) 
     return; // Can't run the task twice 

    _cancellation = new CancellationTokenSource(); 
    _commandTask = new Task(SendSshCommand, _cancellation.Token); 
    _commandTask.ContinueWith(FinishCommand, TaskScheduler.FromCurrentSynchronizationContext()); 

    _commandTask.Start(); 

    // returning control to the UI thread now 
} 

protected void CancelCommand(object sender, EventArgs e) 
{ 
    if(_commandTask == null) 
     return; 

    _cancellation.Cancel(); 
} 

private static void SendSshCommand() 
{ 
    // Send your SSH Commands here 
} 

private void FinishCommand(Task task) 
{ 
    // Update your UI here 

    // remove this task 
    _commandTask = null; 
    _cancellation = null; 
} 

그래서 SendCommand 방법은 당신의 UI에 대한 몇 가지 이벤트에서 호출된다 (버튼 내가 가정 클릭). CancellationTokenSource과 새 Task을 만듭니다. 이 태스크는 별도의 스레드에서 SendSshCommand 메소드를 호출합니다. 그런 다음 ContinueWith 메소드를 사용하여 작업 계속을 만듭니다. TaskScheduler.FromCurrentSyncrhonizationContext()을 전달하면 연속 스레드가 별도의 스레드 대신 UI의 스레드에서 실행하려고한다는 것을 알 수 있습니다. 이것은 UI 스레드에없는 경우 UI 컨트롤에 액세스 할 수 없기 때문에 중요합니다.

CancelCommand은 취소 버튼에서 호출되며 _commandTask에 실행을 중지하도록 지시합니다.

지금은 100 %가 아니므로 작업에 넘어갈 필요가있는 상태를 유지할 것입니다.이 작업을 돕기 위해 Generic Task 구조가 있습니다. 또한 FinishCommand에서 작업을 완료했는지, 취소하지 않았는지, 예외를 throw하지 않았는지 확인하려고 할 것입니다. .Net 4의 Tasks 및 TPL에 대한 정보를 읽으면이를 수행하는 방법을 알 수 있습니다.

취소 후 SSH.NET 라이브러리에서 어떤 일이 발생할 것인지 잘 모르겠다는 점도 유의해야합니다. SSH 세션의 연결을 해제하면 Unix 시스템에서 프로세스가 종료된다고 가정합니다. 그러나 다시 한 번, 특정 라이브러리에 익숙하지 않아 일부 테스트를 수행해야합니다.

희망 하시겠습니까?

+0

감사합니다. 처음 작업에 대한 내용을 먼저 읽어야합니다. – Hershizer33

+0

@Coding Gorilla : Im은 솔루션을 구현하려고 시도하지만 Im은 _commandTask.ContinueWith (stuff) 행에 오류가 발생합니다. 이러한 인수와 일치하는 오버로드가 없음을 말합니다 ... 현재 현재 Tasks에서 읽고있는 중이지만 이게 오타 일 뿐이라는 것을 알기 위해, 감사합니다! – Hershizer33

+0

"물건"이란 무엇입니까? 대리인이나 행동이어야합니다. – CodingGorilla

0

나는 도서관에 익숙하지 않아요하지만 당신은 하나 개의 SSH 세션이있는 경우, 즉, 같은 쉘은 백그라운드 작업으로 명령을 실행하고 킬 %로 1

실행을 취소 : -

명령 &

는 취소 -

kill % 1

이렇게하려면 동일한 쉘에 있어야합니다.

CTRL-C는 작동하는 쉘 전송에 대한 스트림 유형 인터페이스가있는 경우 ASCII 3입니다.

관련 문제