2014-06-19 21 views
0

我有一個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(),而該服務已在處理數據時,它可能是一些真實數據可能無法寫入數據庫。

什麼是更好的方式來禁用查詢測試運行比使用布爾標誌?

+0

Remoting的是保留向後兼容現有的應用程序,因此不建議對新開發的傳統技術。現在應該使用WCF或ASP.NET Web API開發分佈式應用程序。請參閱http://msdn.microsoft.com/en-us/library/vstudio/xws7132e.aspx頂部的註釋以獲取證明。 –

+0

This isnt thread safe .... –

+0

@AK_你讀過這個問題了嗎?這就是整個觀點。 – Dan

回答

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 
} 
+0

提供的示例過於簡化..也許過於簡化。實際上,在DoCalculations()層次結構中隱藏着數十或數百個'UpdateDatabase()'調用。將變量傳遞給50+函數會使參數列表變得醜陋,我需要一個更中心的方法,也是線程安全的。 – Dan

+0

在OP中編輯示例,希望更好地說明這一事實。 – Dan

0

我找到了一個使用ThreadLocal的解決方案。

我編寫了一個簡單的客戶端/服務器測試應用程序,使用.NET遠程處理來驗證遠程調用在新線程上執行,並且使用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; } 
} 
+0

注意:通常我會大寫字段名稱,但我想保持命名與原始示例一致。 – Dan