[英]How to Implement Interface methods into Another Project using Assembly reference in C#?
[英]User Interface halts while using some methods of assembly reference dll
我在控制某些网络设备的C#中使用程序集引用dll! 当我尝试连接网络设备时,用户界面会暂停直到建立连接! 为了解决此问题,我确实使用了线程/异步等待(.Net Framework 4.0),但问题仍未解决。
这是我的代码(使用线程):
public void startListening(string IP, string Port)
{
if (!ThreadBusy)
{
if (IP.Trim() == "" || Port.Trim() == "") return;
Conn = new Thread(() => start(IP, Port));
Conn.Start();
ThreadBusy = true;
}
}
private void start(string IP, string Port)
{
if (!bIsConnected && !isListening)
{
//This Line Will Make UI Freez...
bIsConnected = axCZKEM1.Connect_Net(IP, Convert.ToInt32(Port));
if (bIsConnected == true)
{
iMachineNumber = 1;
deviceType = axCZKEM1.IsTFTMachine(iMachineNumber) ? 1 : 2;
this.IP = IP;
this.isListening = true;
if (axCZKEM1.RegEvent(iMachineNumber, 65535))
{
switch (deviceType)
{
case 1:
EnableTFTEvents();
break;
case 2:
EnableBWEvents();
break;
case 3:
//---
break;
}
ConnectionFailedArgs args = new ConnectionFailedArgs();
args.IP = IP;
OnConnectionSucceed(args);
}
}
else
{
ConnectionFailedArgs args = new ConnectionFailedArgs();
args.IP = IP;
OnConnectionFailed(args);
}
ThreadBusy = false;
}
}
我想知道使用此线程时UI上发生了什么?
我将VS从2010年升级到2012年(.Net Framework 4.5),但问题仍然没有解决!
这是我的代码(使用async-await):
public async void startListening(string IP, string Port)
{
if (!ThreadBusy)
{
if (IP.Trim() == "" || Port.Trim() == "") return;
//Conn = new Thread(() => start(IP, Port));
//Conn.Start();
ThreadBusy = true;
await Task.Run(() => start(IP,Port));
}
}
private async Task start(string IP, string Port)
{
if (!bIsConnected && !isListening)
{
//This Line Will Make UI Freez...
bIsConnected = axCZKEM1.Connect_Net(IP, Convert.ToInt32(Port));
if (bIsConnected == true)
{
deviceType = axCZKEM1.IsTFTMachine(iMachineNumber) ? 1 : 2;
this.IP = IP;
this.isListening = true;
if (axCZKEM1.RegEvent(iMachineNumber, 65535))
switch (deviceType)
{
case 1:
EnableTFTEvents();
break;
case 2:
EnableBWEvents();
break;
case 3:
//---
break;
}
ConnectionFailedArgs args = new ConnectionFailedArgs();
args.IP = IP;
OnConnectionSucceed(args);
}
}
else
{
ConnectionFailedArgs args = new ConnectionFailedArgs();
args.IP = IP;
OnConnectionFailed(args);
}
ThreadBusy = false;
}
}
一个常见的误解是async/await
以某种方式使代码创建线程或由它们异步执行。 他们不。 它们实际上指示编译器执行在另一个线程上调用await
任何异步方法,并在异步方法完成时在原始线程上返回执行。 它是异步方法,它实际上创建和调度Tasks并(间接地)利用线程。
您必须在异步操作上调用await
,否则您的整个方法将在原始(即UI)线程中执行。
这意味着,当您调用Connect_Net时,您仍在UI线程上,您的应用程序将显示为冻结状态。
您应该查看Stephen Toub的文章“ 用await
调用方法... ugh! ”以获取更详细的解释。
最好的解决方案是使用Connect_Net的异步版本(如果有),然后await
它。
private async Task start(string IP, string Port)
{
if (!bIsConnected && !isListening)
{
//This Line Will Make UI Freez...
bIsConnected = await axCZKEM1.Connect_NetAsync(IP, Convert.ToInt32(Port));
...
如果没有这种方法,则可以使用Task.Run异步调用Connect_Net。
private async Task start(string IP, string Port)
{
if (!bIsConnected && !isListening)
{
//This Line Will Make UI Freez...
bIsConnected = await Task.Run(()=>axCZKEM1.Connect_Net(IP, Convert.ToInt32(Port)));
...
await
之后,将继续在原始SynchronizationContext(大约是桌面应用程序的原始线程)上执行。 这意味着如果其余代码需要很长时间才能运行,则UI仍会冻结。
我的猜测是问题出在创建线程时。 告诉我,也许您正在执行Join()
,这可能会导致这种情况,或者您正忙于等待线程结束。
确保您正在创建的线程中没有执行其他操作,然后
Thread t = new Thread(new ThreadStart(MyFunc));
t.Start();
创建线程之后,您无需执行任何操作
while(t.IsAlive == false)
Sleep(20);
如果您想知道线程何时结束,可以调用如下方法:
Invoke(new ThreadEnded(DoSomething));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.