禁用数据库写入的空运行

时间:2014-06-19 21:54:01

标签: c# multithreading remoting

我的Windows服务继承自MarshalByRefObject

在运行时,此服务偶尔会收到一个文件:

  • 从数据库中读取数据
  • 做计算
  • 将结果写入数据库

我想实现一个函数,让我们称之为TestRun(),可以远程调用它:

  • 从数据库中读取数据
  • 做计算
  • 将结果返回给来电者而不向数据库写任何内容

出于显而易见的原因,我希望TestRun()使用与常规服务相同的计算代码,这些服务充满了UpdateDatabase()次调用。

以下是我目前所拥有的简化版本:

static bool commitChanges = true;

public CalcResult TestRun()
{
    try
    {
        commitChanges = false;
        return ProcessData();
    }
    finally
    {
        commitChanges = true;
    }
}

private CalcResult ProcessData()
{
    DataModel data = QueryData();

    //Note: DoCalculations() calls a bunch of other functions with complex
    //      objects many of which make multiple calls to UpdateDatabase().
    CalcResult result = DoCalculations(dataModel);

    return result;
}

private void UpdateDatabase(CalcResult result)
{
    if(commitChanges)
    {
        //Write data to database
    }
}

问题是我很确定如果有人在服务处理数据时调用TestRun(),可能有些实际数据可能无法写入数据库。

与使用布尔标志相比,禁用测试运行查询的更好方法是什么?

2 个答案:

答案 0 :(得分:0)

您可以为ProcessData添加可选参数。

public CalcResult TestRun()
{
    return ProcessData(writeToDatabase: false);
}

private CalcResult ProcessData(bool writeToDatabase = true)
{
    DataModel data = QueryData();

    CalcResult result = DoCalculations(dataModel);

    if (writeToDatabase) UpdateDatabase(result);

    return result;
}

private void UpdateDatabase(CalcResult result)
{
    //Write data to database
}

答案 1 :(得分:0)

我找到了一个使用ThreadLocal的解决方案。

我使用.NET remoting编写了一个简单的客户端/服务器测试应用程序来验证远程调用是否在新线程上执行,并且使用ThreadLocal按预期工作;他们是,而且确实如此。

我换了:

static bool commitChanges = true;

private static ThreadLocal<bool> _commitChanges = new ThreadLocal<bool>(() => true);
private static bool commitChanges
{
    get { return _commitChanges.Value; }
    set { _commitChanges.Value = value; }
}