wcf 서비스와 복잡한 상호 작용을하기 전에 서비스가 살아 있는지 간단한 확인을 수행하는 wcf 클라이언트가 있습니다. 실패한 연결의 시간 제한이 1 분이므로이 검사를 비동기 적으로 구현하려고합니다.다른 스레드에서 서버와 통신하는 동안 WPF UI를 응답 성있게 유지하려면 어떻게해야합니까?
//Method on the main UI thread
public void DoSomeComplicatedInteraction()
{
If(ConnectionIsActive()) DoTheComplicatedInteraction();
}
private bool ConnectionIsActive()
{
//Status is a Textblock on the wpf form
Status.Text = "Checking Connection";
var ar = BeginConnectionIsActive();
while (!ar.IsCompleted)
{
Status.Text += ".";
Thread.Sleep(100);
}
EndConnectionIsActive(ar);
//IsConnected is a boolean property
return IsConnected;
}
private IAsyncResult BeginConnectionIsActive()
{
//checkConnection is Func<bool> with value CheckConnection
return checkConnection.BeginInvoke(null,checkConnection);
}
private void EndConnectionIsActive(IAsyncResult ar)
{
var result=((Func<bool>)ar.AsyncState).EndInvoke(ar);
IsConnected = result;
}
private bool CheckConnection()
{
bool succes;
try
{
//synchronous operation
succes=client.Send(RequestToServer.GetPing()).Succes;
}
catch
{
succes = false;
}
return succes;
}
이 작동 :
이 내가 가진 것입니다. 단, 서버의 Send 메서드에 Thread.Sleep을 추가하여 느린 서버 응답을 시뮬레이트하려고하면 UI가 응답하지 않게됩니다. 또한 상태 텍스트 블록의 텍스트가 눈에 띄게 업데이트되지 않습니다. Application.DoEvents 메서드가 필요합니다. 아니면 다른 방법이 필요합니까?
편집 : 사실 다른 접근 방법이 필요합니다. Thread.Sleep을 사용하면 Main UI 스레드를 호출 할 때 UI가 차단됩니다. 여기 내가 그것을 해결하는 방법입니다
//Method on the main UI thread
public void DoSomeComplicatedInteraction()
{
IfConnectionIsActiveDo(TheComplicatedInteraction);
}
private void TheComplicatedInteraction()
{...}
private void IfConnectionIsActiveDo(Action action)
{
Status.Text = "Checking Connection";
checkConnection.BeginInvoke(EndConnectionIsActive,
new object[] { checkConnection, action });
}
private void EndConnectionIsActive(IAsyncResult ar)
{
var delegates = (object[]) ar.AsyncState;
var is_active_delegate = (Func<bool>) delegates[0];
var action = (Action) delegates[1];
bool is_active=is_active_delegate.EndInvoke(ar);
IsConnected = is_active;
Dispatcher.Invoke(DispatcherPriority.Normal,
new Action<bool>(UpdateStatusBarToReflectConnectionAttempt),is_active);
if (is_active) action();
}
나는 그것이 매우 행복하지 않다 : 그것은 다섯 가지로 두 가지 방법으로로 사용 (동기) 코드를 확산! 이로 인해 코드가 매우 복잡해집니다.
감사합니다. UI가 Thread.Sleep 동안 사용자 작업에 마술처럼 반응하거나 WPF에 해당하는 Application.DoEvents가 존재하기를 기대했습니다. 그것은 어쨌든 나쁜 해결책 인 것 같습니다 – Dabblernl