2016-06-13 6 views
0

シングルトンクラス内でsignalR接続をセットアップしているので、プロジェクト全体で同じ接続を使用できます。問題は、接続が開始されず、コードがawait hubConnection.Start()行を超えて実行されないことです。ただし、これを単一クラス外で実行すると、瞬時に接続が開始されます。私は何が間違っているのだろうか。ここ はシングルトンクラスの私の定義です:シングルトンクラス内でSignalR接続が開始されない

public sealed class ProxySubscriber 
{ 
    private static volatile ProxySubscriber instance; 
    private static object syncRoot = new Object(); 
    private IHubProxy chatHubProxy = null; 
    private HubConnection hubConnection = null; 
    public event Action<string, string> OnConnect; 
    private ProxySubscriber() 
    { 
     if (hubConnection == null) { hubConnection = new HubConnection("http://cforbeginners.com:901"); } 
     if (chatHubProxy == null) { chatHubProxy = hubConnection.CreateHubProxy("ChatHub"); } 

     chatHubProxy.On<string, string>("onConnected", (id, username) => OnConnect.Invoke(id, username)); 
    } 

    private async Task<string> StartConnection() 
    { 
     await hubConnection.Start(); 

     return "Connection started.."; 
    } 

    public async void InvokeConnect() 
    { 
     await chatHubProxy.Invoke("Connect", "Mujtaba"); 
    } 
    public static async Task<ProxySubscriber> GetInstance() 
    { 
     if (instance == null) 
     { 
      lock (syncRoot) 
      { 
       if (instance == null) 
       { 
        instance = new ProxySubscriber(); 

       } 
      } 
     } 

     await instance.StartConnection(); 
     return instance; 
    } 
} 

私はこのようなシングルトンクラスを使用しています:あなたでGetInstance()非同期を作るドント、

ProxySubscriber proxySubscriber = ProxySubscriber.GetInstance().Result; 
proxySubscriber.OnConnect += proxySubscriber_OnConnect; 
proxySubscriber.InvokeConnect(); 

答えて

2

最初のもの。論理を持たないインスタンスを作成するために使用してください。

StartConnectionが公開して呼び出しを待って、外部からそれを呼び出す:

await ProxySubscriber.GetInstance().StartConnection(); 
ProxySubscriber.GetInstance().OnConnect += proxySubscriber_OnConnect; 
ProxySubscriber.GetInstance().InvokeConnect(); 

あなたは非非同期メソッドからこのコードを実行する必要がある場合:

Task.Factory.StartNew(async() => { 
    await ProxySubscriber.GetInstance().StartConnection(); 
    ProxySubscriber.GetInstance().OnConnect += proxySubscriber_OnConnect; 
    ProxySubscriber.GetInstance().InvokeConnect(); 
}); 

詳細:

  1. あなたのクラスの名前が私に似合っていません。 SignalRClientHelperのようなものが良いでしょう。
  2. 疑問の余地なくNULLになるので、コンストラクタのnull値を確認する必要はありませんif (hubConnection == null)
  3. なぜサーバーに「接続」メソッドがありますか? await hubConnection.Start();を実行すると、すでに接続しています。 hubConnection.Headers.Add("username", "Mujtaba");
  4. このクラスを信頼できるものにするには、SignalRの切断を処理する必要があります(しかし、そうすることができます)。これは、接続のユーザー名をアサインするだけの場合は、ヘッダーにそのユーザー名を渡すことができます。別の質問です)
  5. chatHubProxy.Invoke("whatever");を呼び出すたびに、接続が失われた場合に例外が発生し、アプリケーションがクラッシュする可能性があります。 Wrap it in a try/catchステートメントを実行し、必要に応じて例外を処理します。
  6. StartConnectionは、すでに接続が行われているかどうかを確認する必要があります。だから100回呼び出すと、1回だけ接続されます。

一般に、SignalR connection live cycleから学び、接続が失われた時点でいくつかのロジックを実装する必要があります。

は、一見hereを取るherehere

+0

涼しいです。私はこれらの変更を行い、事がよりうまくいくかどうかを見ていきます。第6ポイントについては、既に接続があるかどうかを確認するにはどうすればよいですか? –

+0

また、インスタンスを使用している各フラグメントでStartConnection()メソッドを呼び出す必要がありますか? –

+0

ありがとう!あなたは素晴らしいです!!! –

関連する問題