1

我正在尝试根据此博客在 Silverlight 中实现 SignalR:SignalR 和 Silverlight

当我尝试 .Invoke() 时,出现运行时错误“System.InvalidOperationException:必须先调用 Start 方法才能发送数据。在 Microsoft.AspNet.SignalR.Client.Connection.Send(String data) 在 Microsoft.AspNet .SignalR.Client.Hubs.HubProxy.Invoke[T](String 方法,Object[] args)..."

我的连接上有 _conn.Start() 。如果我在调用之前再次尝试 Start() 它,它会引发异常。这是我的代码:

    private IHubProxy _hub;
    private HubConnection _conn;

    public AddProductView()
    {
        InitializeComponent();
        var url = Application.Current.Host.Source.GetComponents(UriComponents.Scheme | UriComponents.HostAndPort,
                                                                UriFormat.Unescaped);
        _conn = new HubConnection(url);
        _hub = _conn.CreateHubProxy("SilverlightPrism.Mvc.Services.ProductHub");
        _hub.On<string>("NewMessage", message => Deployment.Current.Dispatcher.BeginInvoke(() => DoAddItem(message) ));
        _conn.Start();
    }

    private void DoAddItem(string item)
    {
        var product = DeserializeToProduct(item);
        ProductData.Products.Add(product);
    }

    private void buttonAdd_Click(object sender, RoutedEventArgs e)
    {
        Random random = new Random();
        var id = Guid.NewGuid();
        var product = new Product
            {
                Price = random.Next(1000,100000),
                ProdId = id,
                ProdName = "New prod."
            };
        var jsonMessage = SerializeToJsonString(product);
        _hub.Invoke("SendMessage", jsonMessage);
    }

它在 _hub.Invoke(); 上抛出异常;

如何正确连接集线器并发送消息?

4

1 回答 1

3

HubConnection.Start is asynchronous. You cannot call Start right before Invoke because your HubConnection is probably still in the Connecting state.

You need to wait for the Task returned from Start to complete before you can call IHubProxy.Invoke. You can use await (or Task.ContinueWith if you aren't running .NET 4.5) to ensure Start finishes before you enable buttonAdd.

You could also create your AddProductView object asynchronously in a factory method. Instead of calling HubConnection.Start in the constructor, you could do it in a static Task<AddProductView> CreateAddProductView() method.

Alternatively, if you don't care about the creation of your AddProductView being asynchronous, you can just call Start synchronously:

_conn.Start().Wait();
于 2013-03-23T00:30:03.730 回答