C# 外部函数调用阻止UI线程
我正在开发一个通过以太网与运动控制器对话的应用程序 要连接到控制器,我使用供应商提供的库,要连接,请创建控制器的实例,然后告诉它连接,如果没有控制器,这有可能阻塞几秒钟(没有可控超时)。这会导致UI冻结 为了避免这种情况,我想我可以使用任务在不同的线程中运行连接C# 外部函数调用阻止UI线程,c#,multithreading,.net-4.0,task,C#,Multithreading,.net 4.0,Task,我正在开发一个通过以太网与运动控制器对话的应用程序 要连接到控制器,我使用供应商提供的库,要连接,请创建控制器的实例,然后告诉它连接,如果没有控制器,这有可能阻塞几秒钟(没有可控超时)。这会导致UI冻结 为了避免这种情况,我想我可以使用任务在不同的线程中运行连接 ConnectionTask = Task.Factory.StartNew(() => { try { RMCLink rmc = RMCLink.CreateEthernetLink(Devic
ConnectionTask = Task.Factory.StartNew(() =>
{
try
{
RMCLink rmc = RMCLink.CreateEthernetLink(DeviceType.RMC70, "192.168.0.55");
RMC.Connect();
}
catch
{
this.logger.Log("Failed to connect");
}
}, TaskCreationOptions.LongRunning);
这没有任何效果,UI仍然锁定
我认为我正在正确地使用它们,就好像我用下面的代码替换它一样。UI很好,即使单独的线程在消息出来之前需要几秒钟的时间
ConnectionTask = Task.Factory.StartNew(() =>
{
int x = 1;
while (x != 0) x++;
this.logger.Log("Failed to connect");
}, TaskCreationOptions.LongRunning);
是否有任何方法可以识别正在发生的事情,并防止我对其内部工作一无所知的调用锁定UI线程。使用
异步/等待,大致如下:
public async void MyButton_Click(object sender, EventArgs e)
{
await CreateEthernetLink();
this.logger.Log("Connected!");
}
private async Task CreateEthernetLink()
{
var task = Task.Run(() => {
try
{
RMCLink rmc = RMCLink.CreateEthernetLink(DeviceType.RMC70, "192.168.0.55");
rmc.Connect();
}
catch
{
this.logger.Log("Failed to connect");
}});
await task;
}
wait
将捕获当前线程(或SynchronizationContext
——在本例中是被阻止的UI线程),并在异步工作完成后将其还原
因此,线程都是在后台为您处理的,您应该注意到应用程序中没有什么不同,只是在执行连接时应用程序不再冻结
编辑:我还注意到,在您的代码中,您正在初始化rmc,但在rmc上调用connect。我不认为这是正确的。尽管答案很好,但请考虑将解释与代码一起发布。谢谢这实际上会在调用方的单独线程上执行RMCLink.CreateEthernetLink调用吗?@MickyDuncan我已经添加了一些解释。谢谢。由于CreateEthernetLink内部不执行任何等待,因此此代码将无法工作。因此,它不能被标记为异步。它现在将编译,但将同步运行,因为它内部没有任何等待。因此,它有原始的问题。