我正在尝试为基本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);
仍然没有运气
调用'.ConfigureAwait(continueOnCapturedContext:假);''在DoConnect()'创建新任务时。这将避免使用主线程的默认同步上下文。有关详细信息,请参阅此文章(https://msdn.microsoft.com/zh-cn/magazine/jj991977.aspx)。 – vendettamit