C#,SignalR,Owin自我主持人 - 我无法取消事件

时间:2016-11-25 12:57:03

标签: c# asp.net signalr owin

首先,我很抱歉英语 我尝试为RFID阅读器编写代码,我想使用C#+ SignalR + Owin 我有以下代码。

namespace SignalRSelfHost {
   using System;
   using Microsoft.Owin.Hosting;
   using Microsoft.AspNet.SignalR;
   using Owin;
   using Microsoft.Owin.Cors;
   using ReaderSDK;


   class Program{
      static void Main(string[] args) {
        using (WebApp.Start<Startup>("http://localhost:8080/")) {
            Console.WriteLine("Server running at http://localhost:8080/");
            Console.ReadLine();
        }
      }
   }

   public class Startup {
      public void Configuration(IAppBuilder app) {
         app.UseCors(CorsOptions.AllowAll);
         app.MapSignalR();
      }
   }

   //class for basic reader settings with reader event + event handler
   public class RFIDReader {
      public Reader reader = new Reader();
      //definition event, what I'll fire for MyHub class
      public event Action<string> TagToClient;

      public RFIDReader() {
         try {
            //connect to reader
            reader.Connect("xx.xx.xx.xx");
            // event from reader and handler
            reader.TagsComing += TagsComingHandler;
         }
         catch (Exception ex) {
            Console.WriteLine(ex.Message);
         }
      }

      //handler for event readerTagsComming  
      void TagsComingHandler(Reader sender, Tags packet) {
         foreach (Tag tag in packet) {
           //fire event for MyHub class
           TagToClient(tag.toString());
         }
      }
   }

   //MyHub class for communication via SignalR
   public class MyHub : Hub {
      static RFIDReader rfidreader = new RFIDReader();

      // this method is activated from JavaScript client of course
      // JavaScript client code is not relevant for this example 
      public void ReaderStart() {
        //start of reader reads
        rfidreader.start();
        //here I want unsucribe handler - it doesn't works
        rfidreader.TagToClient -= TagToClientHandler;
        //here I subcribe handler
        rfidreader.TagToClient += TagToClientHandler;      
      } 


      //handler for event TagToClient
      void TagToClientHandler(string tagNumber){
         Console.WriteLine(tagNumber);
      }


      //this method is also activated from JavaScript client
      public void ReaderStop() {
         //stop of readers reads
         rfidreader.stop();
      }

   }

}

我的问题是,我无法编写事件处理程序TagToClientHandler,如果我在MyHub类中重复执行方法ReaderStart,我会从阅读器中获取两次,三次等数据。
我有取消订阅此处理程序,但它没有效果。 有人有什么想法吗?

3 个答案:

答案 0 :(得分:0)

static void TagToClientHandler(string tagNumber){
    Console.WriteLine(tagNumber);
}

定义void TagToClientHandler作为静态应该做的伎俩,否则每次处理程序有另一个引用时 - = =不会删除任何东西

或只是将TagToClient设置为null

rfidreader.TagToClient = null

答案 1 :(得分:0)

Hub实例是瞬态的,您将获得每个请求的新实例。因此,存储应该在多个调用或订阅事件中使用的任何类型的数据都不会起作用。您需要有一个单独的方法来存储其生命周期长于Hub的生命周期但仍可从Hub访问的内容,以便您可以从中心调用方法(最简单的方法可能只是集线器上的静态属性,但是您如果你有多个客户端并且他们都将开始调用方法(也考虑线程),我们需要考虑它是否会起作用。

请注意,Hub类具有OnConnected / OnDisconnected事件,这些事件在您的情况下也可用于跟踪连接。

答案 2 :(得分:0)

问题是你的静态初始化程序

static RFIDReader rfidreader = new RFIDReader();

由于MyHub是瞬态的,因此每次调用都会实例化一个新的。这意味着您在每次通话时都重新初始化rfidreader。您应该向该类添加一个构造函数,检查null并仅在null

时初始化它
public class MyHub : Hub {
   static RFIDReader rfidreader = null;

   public MyHub() {
      if (rfidreader == null) {
         rfidreader = new rfidreader();
   }

...
}