2013-08-07 61 views
2

我在c#中使用程序集引用dll來控制一些網絡設備!當我嘗試連接網絡設備時,用戶界面停止連接建立! 爲了解決這個問題,我沒有使用線程/異步的await(.NET Framework 4.0中),但問題仍然沒有解決......用戶界面停止使用某些方法的程序集引用dll

這裏是我的代碼(使用線程):

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),但問題仍未解決!

這裏是我的代碼(使用異步的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; 
     } 
    } 
+2

'Aync/await'與'Threads'不一樣,它是在.NET 4.5 –

+0

中介紹的我知道!但是我下載了[「Microsoft Visual Studio Async CTP」](http://download.microsoft.com/download/7/B/5/7B59A157-A908-4F6E-85D7-EB93E3A4DC00/Async-CTP-v3.exe)包分開... –

+0

如果你想知道在UI線程上發生了什麼,那麼你需要使用調試器。使用Debug + Windows +線程來選擇它。如果你看到它陷入循環,等待ThreadBusy,那麼你一定會發現問題。 –

回答

0

我的猜測是,這個問題是當你創建線程。告訴我,也許你正在做Join()這可能會導致或者你正忙於等待線程結束。

確保在線程你創建你什麼都沒有做更多的則

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

和創建線程你沒有做這樣的事情

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

後,如果您想知道什麼時候線程結束,你可以調用像這樣的方法:

Invoke(new ThreadEnded(DoSomething)); 
+0

感謝您的快速響應!但問題仍然沒有解決... –

+0

@YounesJafari你能分享你的代碼嗎?我的意思是創建一個新線程的代碼 –

+0

我沒有更新我的帖子... –

1

這是一個常見的錯誤eption async/await以某種方式使代碼創建線程或由微軟異步執行。他們不。他們實際上指示編譯器執行任何異步方法,在另一個線程上調用await,並在異步方法結束時在原始線程上返回執行。這是實際創建和調度任務並(間接)使用線程的異步方法。

您必須在異步操作上調用await,否則您的整個方法將在原始(即UI)線程中執行。

這意味着當您調用Connect_Net時,您仍然在UI線程上,並且您的應用程序將顯示爲凍結狀態。

您應該查看Stephen Toub的文章「Invoke the method with 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)); 
... 

如果沒有這樣的方法,你可以調用Connect_Net異步使用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))); 

... 

await繼續執行對原有的SynchronizationContext(約原來的線程桌面應用程序)。這意味着如果代碼的其餘部分需要很長時間才能運行,UI仍然可以凍結。

+0

Connect_NetAsync不可用,Connect_Net也將返回布爾值...我如何訪問此?它存儲在Task.Result中嗎? –

+0

是的,雖然等待會解開它並返回布爾值 –

+0

我將代碼更改爲您的建議代碼,但問題仍未解決! (UI停止!) –

相關問題