2012-03-29 111 views
1

我在Final()方法中遇到了一些麻煩。它應該返回IWeather的列表,但在我調用它時返回null。在調試我停在什麼都不返回

return this.returner; 

,但它總是空,我不知道爲什麼,因爲MainMethod()返回「完成」,並列出「武者回歸」不爲空時,調試是MainMethod()。

using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Net.NetworkInformation; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Activation; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 
using LibW; 

[ServiceContract(Namespace = "")] 
[SilverlightFaultBehavior] 
[AspNetCompatibilityRequirements(RequirementsMode =  AspNetCompatibilityRequirementsMode.Allowed)] 
public class AllInOne 
{ 
[OperationContract] 
public void DoWork() 
{ 
    // Add your operation implementation here 
    return; 
} 
[DataMember] 
private List<LibW.IWeather> returner = new List<LibW.IWeather>(); 
/// <summary> 
/// method set connection to google and get xml document weather for there 
/// </summary> 
/// <param name="city">city for which find weather</param> 
/// <param name="lang">lang of text</param> 
/// <returns>return either "finish if all successful or Exception msg or errors with city finding and error with connection</returns> 
[OperationContract] 
public string MainMethod(string city, string lang) 
{ 
    //check connection 
    Ping p = new Ping(); 
    PingReply pr = p.Send(@"google.com"); 
    IPStatus status = pr.Status; 
    if (status != IPStatus.Success) 
     return "Error with Connection"; 
    //try tp get xml weather 
    try 
    { 
     XElement el; 
     HttpWebRequest req = 
      (HttpWebRequest) WebRequest.Create("http://www.google.com/ig/api?weather=" + city + "&hl=" + lang); 
     HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); 
     StringBuilder sb = new StringBuilder(); 
     using (StreamReader streamreader = new StreamReader(resp.GetResponseStream(), Encoding.GetEncoding(1251))) 
     { 
      el = XElement.Load(streamreader); 
     } 
     int addv = 0; 
     var v = from c in el.Elements() 
       select c; 

        //I get here data from XML(condition,temperature and etc.) 

     return "finish"; 
    } 
    catch (Exception exc) 
    { 
     return exc.Message; 
    } 
} 

/// <summary> 
/// return list of weather fot 4 days 
/// </summary> 
/// <returns>list</returns> 
[OperationContract] 
public List<IWeather> Final() 
{ 
    return this.returner; 
} 
} 
+0

當你說'returner'是'null'時,你真的指'null'還是你的意思是它是一個空的'List <>'? – 2012-03-29 16:57:26

回答

3

您的服務由兩個單獨的操作組成,並使用服務類上的成員變量嘗試在調用之間存儲狀態。您也沒有在您的服務等級上指定任何明確的ServiceBehaviorAttribute,這意味着默認InstanceContextMode將是PerSession。但是,我猜你現在實際上並沒有使用會話,所以你基本上以PerCall行爲結束。

那麼,發生了什麼是電話打進來了MainMethod,是可以獲得AllInOne服務類的新實例,它執行,填補了returner領域,但現在情況等做準備GC'd。下一次撥打Final會得到一個AllInOne類的全新實例,因此returner字段永遠不會被設置,因此爲空。

你要麼需要使用SingleInstanceContextMode如果你想要一個實例爲所有的客戶(也許你只能有一個,不知道)實際上你需要啓用該服務會話,並確保你的客戶也正確使用會話。有關如何使用會話的詳細信息,請參見here

+0

是的,我只有一個客戶端。 – 2012-03-29 17:14:40

+1

好吧,一旦你使它成爲單例,它會保留這個值,直到主機關閉(IIS應用程序池,windows服務,無論你在運行它)爲止。因此,您需要確保客戶端在要強制更新值時始終調用MainMethod。老實說,你應該改變你的API設計,返回「完成」或錯誤消息不是Web服務應該如何工作。如果出現錯誤,應該在其中引發一個FaultException錯誤消息。如果你這樣做了,你可以從MainMethod本身返回List ,並且沒有任何這些問題。 – 2012-03-29 17:32:20

+0

問題是我想知道它是連接錯誤還是隻是城市或語言不正確,所以在完整版本中它不僅返回!完成!或!連接錯誤!但也 !錯誤的城市或錯誤的語言! – 2012-03-29 17:47:55

1

因爲每次創建WCF請求時都會創建類的新實例,所以在調用WCF服務之間局部變量不是永久的。您的所有請求都需要彼此獨立,否則您需要持久存儲容器,如數據庫。或者您需要使用會話,如@DrewMarsh所示。

+0

在這種情況下,'returner'不會是'List <>'而不是'null'嗎?我認爲和你的答案一樣,但是我認爲整個班級都會爲每個電話重新實例化。 – 2012-03-29 16:54:25

+0

我假設OP濫用單詞'null'這意味着沒有數據,不一定是它實際上是'null'。 – mellamokb 2012-03-29 16:56:02

+0

這是一個很好的觀點。 OP可能會有一個假設。 – 2012-03-29 16:56:55

1

當我調查你的代碼時,我覺得你對WCF有點困惑。首先,除非您從客戶端調用WCF中的操作合同,否則它本身不起作用。例如,當你調用final方法時,它只返回一個列表。 另外,在mainmethod中,你返回了一個字符串,它是完成的。 「完成」不是一個方法調用,只是一個字符串。