2012-12-14 116 views
0

请考虑下面的简单代码,然后我会问我的问题。测试代码 - 如何在测试环境中绕过线程

public static void Save(XmlDocument saveBundle) 
    { 
     ThreadStart threadStart = delegate 
     { 
      SaveToDatabase(saveBundle); 
     }; 

     new Thread(threadStart).Start();    
    } 

在Visual Studio(2005)使用线程的问题是你不能穿行其中容易(我相信有一种方法来切换,我还没有研究,因为我希望有螺纹一个更简单的方法)。

所以,在现场,我的代码更复杂,然后上面的例子,我们使用一个新的线程,因为它是时间关键,但主体是一样的。最重要的是,它在测试中不是时间关键!

目前,我可能会做一些类似于使用#if debug的东西,但这样做只是感觉不对 - 我是否正确使用#if或者有更好的方法来解决这个问题?

public static void Save(XmlDocument saveBundle) 
    { 

    #if debug 
     { 
     SaveToDatabase(parameters); 
     } 
    #else 
     { 
      ThreadStart threadStart = delegate 
      { 
       SaveToDatabase(parameters); 
      }; 

      new Thread(threadStart).Start(); 
     } 
    #endif 
     } 
    } 

虽然我卡在.NET 2.0我很感兴趣,从.NET 20起任何版本(我相信有一天我会离开侏罗纪时期并加入其他人)

回答

1

如果你真正想要做的不是在你的调试版本中使用线程 - 这是做到这一点的正确方法,也可能是最快和最有效的方式。它可能看起来有点丑,但替代方案只是更多的布尔,配置和其他解决方法。

如果您有兴趣直接调试线程(这很重要,也许如果并发是一个问题!您应该总是尽可能接近生产环境进行测试),那么您可以简单地去(调试 - > Windows - >线程),然后右键单击您想要调试的线程和“切换到线程”。

2

我会说你的原代码缺乏一个重要的功能;某种汇报的机制,当操作完成(或失败):

public static void Save(XmlDocument saveBundle, Action<Exception> completedCallback) 
{ 
    ThreadStart threadStart = delegate 
    { 
     try 
     {    
      SaveToDatabase(saveBundle); 
      completedCallback(null); 
     } 
     catch (Exception ex) 
     { 
      completedCallback(ex); 
     } 
    }; 

    new Thread(threadStart).Start();    
} 

这样的话,你可以使用某种同步方法来协调你的单元测试:

Exception actualException = null; 
using (AutoResetEvent waitHandle = new AutoResetEvent(false)) 
{ 

    instance.Save(xmlDocument, ex => 
    { 
     actualException = ex; 
     waitHandle.Set(); 
    }); 
    waitHandle.WaitOne(); 
} 

Assert.IsNull(actualException); 
0

也许你可以把这个线程代码放到一个单独的方法中,并在测试时替换该方法。

virtual void SaveToDBInSeparateThread(...) 
{ 
    ThreadStart threadStart = delegate 
    { 
     ... 
    }; 

    new Thread(threadStart).Start(); 
} 

然后,你可以不返回void返回线程运行或类似的东西。

或者你可以像下面添加一个输入参数,以你的方法:

virtual void SaveToDB(bool inSeparateThread) 
{ 
    if(inSeparateThread) 
    { 
     ThreadStart threadStart = delegate 
     { 
     ... 
     }; 

     new Thread(threadStart).Start(); 
    } 
    ... 
} 

也可以提供某种DatabaseSavingContext的:

interface IDBSaveContext 
{ 
    public void SaveToDB(...) 
} 

,并使用不同的实现(螺纹,非螺纹)取决于执行类型。

+0

bool与条件几乎完全相同 - 并且仅增加了一点额外的头部。 –

+0

是的,的确如此。我只是提出了这样的选择,因为问题的作者对预处理器条件感到不舒服。 –