2015-12-29 35 views
1

我正在尝试为基本Telnet会话使用第三方Telnet库“活动专家”。 在我的UI代码后面我有类似针对阻塞UI线程的特殊线程的持续运行进程

private async void Button_Click(object sender, RoutedEventArgs e) 
    {   
     var ts = new TelnetService(); 
     await ts.DoConnect(node); 
    } 

和我TelnetService看起来像这样

public class TelnetService 
{ 
    private Tcp objSocket = new Tcp(); 
    private NwConstants objConstants = new NwConstants(); 
    public string Responses { get; set; } 
    private Timer timer1 = new Timer(); 

    public TelnetService() 
    { 
     timer1.Elapsed += timer1_Elapsed; 
     timer1.Interval = 100; 
     timer1.Start(); 
    } 
    void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     if (objSocket.ConnectionState == objConstants.nwSOCKET_CONNSTATE_CONNECTED) 
     { 
      if (objSocket.HasData()) 
      { 
       Responses += objSocket.ReceiveString() + "\r\n"; 
      } 
     } 
    } 

    public Task DoConnect(Node node) 
    { 
     return Task.Factory.StartNew(() => 
     { 
      objSocket.Protocol = objConstants.nwSOCKET_PROTOCOL_TELNET; 
      objSocket.Connect(node.IP, 23); 

      while (true) 
      { 
       if ((Responses == null) || (!Responses.Contains(node.WaitString))) continue; 
       //do something 
       Responses = ""; 
       break; 
      } 
     }); 
    } 

} 

有功能的两个重要部分。

首先在timer1_Elapsed函数是一个进程将继续破坏并检查是否有套接字上的数据,如果有,它会将它附加到一个字符串“响应”。我正在使用“计时器”。

第二个在DoConnect函数,它将检查某个输入的“响应”字符串。为此我使用异步等待和任务。

简而言之,第一个积累响应和第二个检查响应。

问题是,它看起来像在一般的计时器代码和

objSocket.ReceiveString() 

线特别是导致UI线程停止几秒钟。这意味着点击按钮后,我无法将主窗体移动到屏幕上,但是代码在单独的线程中运行。 我已经尝试过使用纯线程,但它也没有帮助。

更新

代替计时器我使用的方法AccumulateResponse

public static void AccumulateResponse() 
    { 
     while (true) 
     { 
      if (objSocket.ConnectionState == objConstants.nwSOCKET_CONNSTATE_CONNECTED) 
      { 
       if (objSocket.HasData()) 
       { 
        Responses += objSocket.ReceiveString() + "\r\n"; 
       } 
      } 
     } 

    } 

,并要求它像

var t = new Task(TelnetService.AccumulateResponse);   
     t.Start(); 
     await TelnetService.DoConnect(node); 

仍然没有运气

+0

调用'.ConfigureAwait(continueOnCapturedContext:假);''在DoConnect()'创建新任务时。这将避免使用主线程的默认同步上下文。有关详细信息,请参阅此文章(https://msdn.microsoft.com/zh-cn/magazine/jj991977.aspx)。 – vendettamit

回答

0

DoConnect不你的问题EM。这是你的Timer Elapsed事件处理程序。

定时器已用事件不是异步的。只有DoConnect是。

如果您的第三方库没有异步版本ReceiveString(),那么在async timer1_elapsed方法中使用Task.Run

+0

确保生病尝试,并让你知道 –

+0

如果生病使用Task.Run内经过它将运行在每个刻度的任务。我们想要那个吗? –

+0

我已经更新了我的另一个答案尝试 –