2015-06-21 39 views
0

我有一個Windows窗體,其中包含一個列表框(Listbox1),一個標籤(label1)和一個按鈕(button1)。我已經指派一個click事件button1,代碼如下:如何計算C#中更新的列表框中的條目?

public void button1_Click(object sender, EventArgs e) 
{     
    label1.Text = "Parsing entries && initializing comms ..."; 

    apples = new Task(Apple); 
    apples.Start(); 
    Task.WaitAll(apples); 

    label1.Text = "No. of items: " + Listbox1.Items.Count.ToString(); 

    if (Listbox1.Items.Count >= 2) 
    { 
     Listbox1.SetSelected(1, true); 
    } 
} 

public void Apple() {  
//Send 1st command - 90000 
command = "90000"; 
CommPort com = CommPort.Instance; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 

//Send 2nd command - 90001 
command = "90001"; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 

//Send 3rd command - 90002 
command = "90002"; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 

//Send 4th command - 90003 
command = "90003"; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 

//Send 5th command - 90004 
command = "90004"; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 

//Send 6th command - 90005 
command = "90005"; 

if (command.Length > 0) 
{ 
command = ConvertEscapeSequences(command); 
com.Send(command); 
} 
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port 
//Listbox1 eventually contains some (~6) entries 
} 

然而,當我點擊button1label1顯示文本No. of items: 0,雖然Listbox1實際上包含6個項目。爲什麼代碼在Listbox1中有6個項目時返回0?

+0

您的應用程序是否凍結或是否仍然響應?你不應該在UI線程上使用阻塞調用,比如'WaitAll',因爲這會導致死鎖。 –

+0

Ned的評論是正確的,因爲你不應該在UI線程上用'Task.WaitAll()'阻塞。但是,除了這個問題,您提供的代碼並不能解釋計數不匹配:'(Listbox1.Items.Count).ToString()'是正確的,應該顯示當前在'Listbox1'中的項目數。還有其他一些事情正在發生。 –

+0

@特殊醬,我同意。我只是想了解有關該計劃行爲的更多信息。我懷疑我們需要知道'Apple()'裏面發生了什麼, –

回答

1

您不應該在UI線程上使用阻塞調用,例如WaitAll,因爲這會導致死鎖,更好的選擇是使用async-await

關於異步等待here的最佳實踐有一篇很好的文章。

您只能使用await一個async mehtod裏面,所以你將需要button1_Clickasync然後await調用Apple

,你await需要返回的方法TaskTask<T>所以Apple的返回值將需要改變其中的一個。您可以使用Task.Run向線程池發送任何同步阻塞調用,但必須在線程池上運行的Task.Run委託外部的主線程上訪問任何GUI元素。

public async void button1_Click(object sender, EventArgs e) 
{     
    label1.Text = "Parsing entries && initializing comms ..."; 
    await Apple(); 

    label1.Text = "No. of items: " + ((Listbox1.Items.Count).ToString()); 

    if (Listbox1.Items.Count >= 2) 
    { 
     Listbox1.SetSelected(1, true); 
    } 
} 

public async Task Apple() 
{ 
    await Task.Run(()=> 
     { 
      // serial comms work ...    
     } 

    // add items to list here ... 
} 

如果你的串行通信的API supprts async,即SendAsync,你可以awaitSendAsync調用和使用await Task.Delay(100)做異步睡覺,你不需要Task.Run

+0

謝謝,這完美地工作[除了缺少''; &當加上適當的'await Apple.Delay(..)'命令]。 :) –