2

I'm using an assembly reference dll in c# that controls some network devices! when I try to connect network device, the user interface halts till connection establish! To solving this problem I did use threads/ async-await (.Net Framework 4.0) but the problem is still not solved...

here is my code (using thread):

    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;
        }
    }

I want to know what happening on UI while using this thread?

I Upgrade my VS from 2010 to 2012 (.Net Framework 4.5) but The problem is still not solved!

Here is my code (using 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;
        }
    }
4

2 回答 2

1

It is a common misconception that async/await somehow make code create threads or execute asynchronously by themsleves. They do not. They actually instruct the compiler to execute any asynchronous method on which you call await on another thread and return execution on the original thread when the asynchronous method finishes. It is the asynchronous method that actually creates and schedules Tasks and (indirectly) makes use of threads.

You have to call await on an asynchronous operation, otherwise your entire method will execute in the original (ie the UI) thread.

This means that when you call Connect_Net you are still on the UI thread and your application will appear frozen.

You should check Stephen Toub's article "Invoke the method with await ... ugh!" for a more detailed explanation.

The best solution is to use an asynchronous version of Connect_Net, if there is one available, and await on it eg.

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));
...

If there is no such method, you can call Connect_Net asynchronously using Task.Run

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)));

...

After await execution continues on the original SynchronizationContext (roughly the original thread for desktop applications). That means the UI can still freeze if the rest of the code takes a long time to run.

于 2013-08-07T13:50:28.727 回答
0

my guess is that the problem is when you create the thread. tell me, maybe you're doing Join() which might cause that or you're in a busy wait waiting for the thread to end.

make sure that in the thread you're creating you're not doing anything more then

     Thread t = new Thread(new ThreadStart(MyFunc));
     t.Start();

and after creating the thread you're no doing something like

while(t.IsAlive == false)
   Sleep(20);

if you want to know when the thread ended you can invoke a method like so:

Invoke(new ThreadEnded(DoSomething));
于 2013-08-07T11:49:23.227 回答