问题描述
所以我有一个C#client
,它调用SignalR method
的{{1}},集线器将返回一个hub
。
但是我现在遇到的行为是DateTime
被卡在client
上,最终导致记录以下内容:
HubProxy.Invoke
这是Possible deadlock detected. A callback registered with "HubProxy.On" or "Connection.Received" has been executing for at least 10 seconds.
的代码:
client
这是private async Task<long> GetCurrentServerTimeOffset()
{
DateTime requestDate = DateTime.Now;
DateTime serverDate = await hubProxy.Invoke<DateTime>("GetCurrentServerTime");
DateTime resultDate = DateTime.Now;
long offset = serverDate.Ticks - (requestDate.Ticks + resultDate.Ticks) / 2;
return offset;
}
的代码:
Hub
我已经尝试将public DateTime GetCurrentServerTime()
{
return DateTime.Now;
}
替换为await hubProxy.Invoke<DateTime>("GetCurrentServerTime")
,但其行为相同...
有人知道我在做什么错,导致记录了致命警告吗?
EDIT1 :如果我在hubProxy.Invoke<DateTime>("GetCurrentServerTime").Result
的{{1}}中放置一个断点,则该断点将被命中,而return DateTime.Now;
可以毫无问题地发送响应到hub
。
解决方法
这很奇怪,但是对于我来说,您的代码运行良好。客户端/服务器配置可能有问题吗?
我的简单服务器配置:
public partial class FormServer : Form
{
private IDisposable Server { get; set; }
private const string ServerURL = "http://localhost:8080";
public FormServer()
{
InitializeComponent();
}
private void ButtonStart_Click(object sender,EventArgs e)
{
Task.Run(StartServer);
}
private void StartServer()
{
try
{
Server = WebApp.Start(ServerURL);
this.Invoke((Action)(() => buttonStart.Enabled = false));
consoleTextBox.Invoke((Action)(() => consoleTextBox.AppendText($"Server successfully started on {ServerURL} {Environment.NewLine}")));
}
catch (TargetInvocationException ex)
{
consoleTextBox.Invoke((Action)(() => consoleTextBox.AppendText($"Server failed to start. Error: {ex.Message} {Environment.NewLine}")));
return;
}
}
}
客户端配置:
public partial class FormClient : Form
{
private string ServerURL = "http://localhost:8080";
public HubConnection Connection { get; set; }
IHubProxy HubProxy { get; set; }
public FormClient()
{
InitializeComponent();
labelAddress.Text = ServerURL;
}
private void Connection_StateChanged(StateChange obj)
{
this.Invoke((Action)(() =>
{
labelState.Text = Connection.State.ToString();
if (Connection.State == ConnectionState.Disconnected)
{
buttonConnect.Enabled = true;
}
}));
}
private async Task ConnectAsync()
{
Connection = new HubConnection(ServerURL);
HubProxy = Connection.CreateHubProxy("MyHub"); // Hub name
Connection.StateChanged += Connection_StateChanged;
try // try to connect to the server
{
await Connection.Start();
labelState.Text = Connection.State.ToString();
}
catch (HttpRequestException ex) // Catch an error
{
this.Invoke((Action)(() =>
{
richTextBox.AppendText($"Error: {Environment.NewLine} {ex.Message} {Environment.NewLine}");
}));
}
}
private async void ButtonConnect_Click(object sender,EventArgs e)
{
await ConnectAsync();
}
private async void MyButton_Click(object sender,EventArgs e)
{
long result = await GetCurrentServerTimeOffset();
MessageBox.Show(result.ToString());
}
private async Task<long> GetCurrentServerTimeOffset()
{
DateTime requestDate = DateTime.Now;
DateTime serverDate = await HubProxy.Invoke<DateTime>("GetCurrentServerTime");
DateTime resultDate = DateTime.Now;
long offset = serverDate.Ticks - (requestDate.Ticks + resultDate.Ticks) / 2;
return offset;
}
}
SignalR集线器:
public class MyHub : Hub
{
public DateTime GetCurrentServerTime() => DateTime.Now;
}
,
能够通过不等待它自己修复它:
_radioHubProxy.Invoke<DateTime>("GetCurrentServerTime").ContinueWith(response =>
{
DateTime serverDate = response.Result;
DateTime resultDate = DateTime.UtcNow;
long offset = serverDate.Ticks - (requestDate.Ticks + resultDate.Ticks) / 2;
_mobi.SetServerTimeOffset(offset);
});