使用Multi thread如果結合Queue使用,當在Unit test時會導致錯誤。本次案例是使用Queue儲存資料,並在thread中取得此Queue的資訊,然後再進行處理比對「原始數*2是否等於目標數」。
本次範例為「Day28_MultiThread.cs」
在此範例中,有一個Thread持續監聽是否Queue內有資料,如果有的話就要比對目標數是否為原始數的兩倍。
首先我們先製作要比對的function,Equal2Times()
:
public bool Equal2Times(int targetNumber, int testNumber)
{
if (targetNumber * 2 == testNumber)
return true;
else
return false;
}
接著建立一個Thread需要的功能與參數。會有參數Queue
的CounterQue
,以及紀錄結果的status
。還有Thread執行的function,CompareNumbers()
。此function會持續監聽,監聽counterQue是否有資料,如果有將進行解析後比對:
public Queue counterQue = new Queue();
public bool status = false; //var: correct = true. incorrect = false/
public void CompareNumbers()
{
while (true)
{
if(counterQue.Count > 0)
{
int[] numberArray = (int[])counterQue.Dequeue();
status = Equal2Times(numberArray[0], numberArray[1]);
}
}
}
然後建一個建構子,讓此物件被建立的時候就建立一個Thread進行監聽的工作。
public Day28_MultiThread()
{
Thread thread = new Thread(CompareNumbers);
thread.Start();
}
最後是Unit test的部分,建立一個Day28_MultiThread
,並且把這個物件內的Queue增加新的變數進去。
從邏輯來看,這樣的Thread是個非常簡單的示範,但是在執行後,卻跑出「失敗」,仔細看發現,這並不是「錯誤」,有正常的運作,是一個「預期錯誤」,也就是我們認為答案是要true
,結果回傳值是false
。此部分可能為:此部分的Unit test並不會正常依照我們邏輯的順序,所以導致目標數(4)的1/2非原始數(2)。
class Day28_MultiThread_test
{
[TestCase(2, 4)]
public void Equal2Times_PutNumber_ReturnTrue(int targetNO, int testNO)
{
Day28_MultiThread testObj = new Day28_MultiThread();
testObj.counterQue.Enqueue(new int[2] { targetNO, testNO });
//bool result = testObj.Equal2Times(targetNO, testNO);
bool result = testObj.status;
Assert.AreEqual(result, true); //will be error
}
}
至於為什麼發生的原因,目前還沒有找到相關資訊。推估,雖有建立thread和這個thread的參數,但是此thread還在處理中,所以無法馬上回覆result
,因此導致回傳值為預設值:false。
當我找到原因會再更新文章。
如果知道為什麼發生此問題,還請不吝告知。
PS:祝大家新年快樂~