iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 28
0
Software Development

【Unit Test】Unit Test with C#系列 第 28

【Day 28】狀況雜談3-Multi thread 多執行緒(使用Queue)

使用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需要的功能與參數。會有參數QueueCounterQue,以及紀錄結果的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:祝大家新年快樂~


上一篇
【Day 27】狀況雜談2-Multi thread 多執行續
下一篇
【Day 29】初談Unit test程式撰寫架構
系列文
【Unit Test】Unit Test with C#31

尚未有邦友留言

立即登入留言