繁体   English   中英

使用汇编参考dll的某些方法时,用户界面暂停

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM