我正在开发一个Winforms应用程序,该应用程序通过SignalR客户端执行SQL过程。我对使用SignalR还是比较陌生,但仍会坚持不懈。
我首先运行连接方法来建立与SignalR服务的连接。我有两个配置好的地址,可以在我推送时使用,但DEV配置会导致我在本地托管的SignalR服务。
与SignalR(ConnectHub)的连接
private async Task ConnectHub()
{
string hubAddress = "";
#if DEBUG
HubAddress = ConfigurationManager.AppSettings["HubAddress_DEV"];
#else
HubAddress = ConfigurationManager.AppSettings["HubAddress_PROD"];
#endif
if (string.IsNullOrEmpty(hubAddress))
{
MessageBox.Show("Hub Address is missing from configuration.");
}
ConnectionHandler.Client = new HubClient(hubAddress, "MyHub");
ConnectionHandler.Client.MyAlert += ConnectionHandler.ClientOnMyAlert;
ConnectionHandler.Client.ServerErrorEvent += ConnectionHandler.ClientOnServerErrorEvent;
await ConnectionHandler.Client.Connect(new List<string>() {
VehicleInfo.ThisVehicle.WarehouseCode,
VehicleInfo.ThisVehicle.VehicleName
});
}
我的客户端全局存储在ConnectionHandler类中,该类也保留了我的事件处理程序。 (我有这些断点,因为我还没有实现它们)
ConnectionHandler类
public static class ConnectionHandler
{
public static HubClient Client { get; set; }
public static void ClientOnServerErrorEvent(string error)
{
throw new NotImplementedException(); //Currently not implemented
}
public static async Task ClientOnMyAlert(EnumMyAlertType alerttype, string message, Exception exception)
{
await Task.Yield(); //Currently not implemented
}
}
当我在我的SignalR客户端中调用代码来调用该过程时,它会向我返回一个DataTable,这是预期的结果。 致电SignalR
await ConnectHub();
DataTable dt = await ConnectionHandler.Client.Connection.InvokeCoreAsync<DataTable>(
"FetchStatuses",
new object[0]); //This call works as intended and returns a populated DataTable
StatusInfo = new CStatuses();
以上所有代码当前都在主窗体上完成,但是我想将对SignalR的调用移到构造函数中,以尝试整理事物。
问题出在我尝试将调用移至另一个方法时,程序挂起,因为我认为它没有收到SignalR的返回值,我在其下面放置了一个断点,但未到达该断点。 TryCatch毫无异常,因为它挂在“ Try”中没有任何异常。
从施工方打电话
public CStatuses()
{
Statuses = new List<CStatus>();
var dataTable = ConnectionHandler.Client.Connection.InvokeCoreAsync<DataTable>("FetchStatuses",
new object[0])
.Result; //My program hangs on this line and proceeds no further
当我可以从表单中从客户那里获得价值,并且当我团队的其他成员试图做同样的事情时,我也迷惑了为什么这样做,他们也可以从另一种方法。
有人对我如何进行这项工作有任何想法吗?
我意识到这已经很长了,但是如果我能详细说明一下,请告诉我
要解决的固定代码:
我已将代码从CStatuses构造函数移到同一类中的新异步方法中,并在初始化后调用它。这样就不需要了.Result
,似乎可以为我解决问题了。
public async Task PopulateStatuses()
{
var dataTable = await ConnectionHandler.Client.Connection.InvokeCoreAsync<DataTable>("FetchStatuses",
new object[0]);
Statuses = new List<CStatus>();
foreach (DataRow row in dataTable.Rows)
{
var status = new CStatus
{
StatusId = Common.Utility.GetInt16Value(row["StatusID"]),
StatusCode = Common.Utility.GetStringValue(row["StatusCode"]),
Description = Common.Utility.GetStringValue(row["Description"])
};
Statuses.Add(status);
}
}
答案 0 :(得分:1)
您将通过.Result调用陷入僵局,建议您在CStatuses类中创建一个异步方法,并在初始化CStatuses类后调用websocket获取数据。