NullReferenceException单例实例

时间:2014-10-22 12:43:48

标签: c# azureservicebus

我有以下代码(重要位):

while(true){
  BrokeredMessage message = subscriptionClient.Receive();

  if (message.Properties.ContainsKey("MessageType"))
  {
      try
      {
          SmsService.Instance.SendSms("lenio", user.PhoneNumber, SomeString);
      }
      catch (Exception ex)
      {
          throw;
      }
   }
}

代码连续运行,我收到的消息被处理,SomeString只是一些字符串。

SmsService类如下所示:

public class SmsService
{
    private const string Username = "******";
    private const string Password = "******";
    private static SmsService _instance = null;
    private static readonly Lazy<SmsService> lazy =
    new Lazy<SmsService>(() => new SmsService());


    private SmsService() { }

    public static SmsService Instance
    {
        get
        {
            return lazy.Value;
        }
    }

    public bool SendSms(string from, string receiver, string message)
    {
        string url = UrlBuilder(from, receiver, message);

        HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(url);
        HttpStatusCode statusCode = new HttpStatusCode();

        try
        {
            HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();
            statusCode = response.StatusCode;
        }
        catch (WebException we)
        {
            statusCode = ((HttpWebResponse)we.Response).StatusCode;
        }

        if (statusCode == HttpStatusCode.OK)
        {
            Logger.Instance.AddToLog(0, "SMS", "Sms Send to: +" + receiver);
            return true;
        }
        else
        {
            Logger.Instance.AddToLog(0, "SMS", "Failed to send sms to: +" + receiver);

            return false;
        }

    }
    public string NewLine()
    {
        return "%0a";
    }

    private static string UrlBuilder(string from, string to, string message)
    {
        string newTo = "45" + to;
        string encodedMessage = message.Replace(" ", "+");
        string encodedfrom = from.Replace(" ", "+");

        return "http://sms.sms1290.dk/?username=" + Username + "&password=" + Password + "&to=" + newTo + "&from=" + encodedfrom + "&message=" + encodedMessage;
    }
}

我有一个问题,有时候,如果我收到很多消息,我会得到一个&#34;对象引用未设置为对象的实例。&#34; SmsService上的异常。我有时也得到一个&#34;操作超时&#34;于:

HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();

如果需要,我已经提出了更多代码的要点:https://gist.github.com/Niclassg/54b908fbf5cc9b3e11a7

Stacktrace on&#34;操作超时&#34;:

>   lenioServiceBus.exe!lenioServiceBus.SmsService.SendSms(string from, string receiver, string message) Line 44    C#
lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 489   C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code] 

第44行:

            catch (WebException we)
        {
            statusCode = ((HttpWebResponse)we.Response).StatusCode;  //<-- Line 44
        }

第489行:

if (user.NotifyBySms)
                {
                    Console.WriteLine("Notify user : " + user.Name + " by phone on number: " +
                                      user.PhoneNumber);
                    string msg = "Alarmen i dit hus er nu deaktiveret. ";
                    SmsService.Instance.SendSms("lenio", user.PhoneNumber, msg);  //<-- Line 489
                    //Notify user! (alarm now deactive)
                }
                else
                {
                    Console.WriteLine("Notify user: " + user.Name + "on smartphone");
                    //Notify user! (alarm now deactive)
                }

第59行:

 if (msgHandler(message))  //<-- Line 59
            {
                Logger.Instance.SaveLog();
                try
                {
                    message.Complete();
                }
                catch (Exception ex)
                {
                    //We  might have lost the lock on the message and were too slow to handle it! (Use RenewLock)
                }

            }
            else
            {
                Logger.Instance.SaveLog();

                message.Abandon();
            }

操作超时异常总是跟随具有此堆栈跟踪的nullexception:

>   lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 507   C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code] 

第507行:

catch (Exception ex) //the ex contains the "{"Object reference not set to an instance of an                   object."} exception
        {
            Logger.Instance.AddToLog(2, "AlarmDeactivate", "Failed to deactivate alarm on communicationdevice: " + message.Properties["cdId"] + " with exception: " + ex.Message); //<--Line 507
            return false;
        }

如果我在其他消息完成之前发送消息,我发现我收到此错误。我需要一个解决方案。

1 个答案:

答案 0 :(得分:0)

如果远程主机没有返回响应,那么第44行的we.Response为null,因此读取StatusCode属性的尝试将失败(&#34;对象引用未设置&#34;)。 / p>

您需要更改异常处理(第44行),并不总是假设WebException有响应。

也许是这样的:

statusCode = HttpStatusCode.ServiceUnavailable; // set a default
...
try
{
    ...
}
catch (WebException we)
{
    if (we.Response != null)
    {
        statusCode = ((HttpWebResponse)we.Response).StatusCode;
    }
}

你说:&#34;操作超时异常总是跟随具有此堆栈跟踪的nullexception&#34;

您正在与之通信的服务仅限于一次处理一个请求。无论是否有意,你可能无法做任何事情来修复&#34;那。我此时最好的想法是在SendSms()方法中简单地锁定通信,这样您一次只允许一个请求进行通信。这可能会引入可扩展性问题,但肯定会比简单的失败更好。