无法从不同的方法 return 来自 SignalR 客户端的值
Unable to return a value from SignalR Client from a different method
我正在开发一个通过 SignalR 客户端执行 SQL 程序的 Winforms 应用程序。我对使用 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 class 中,我的事件处理程序也保存在那里。 (我在这些上有断点,因为我还没有实现它们)
连接处理程序Class
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 客户端中调用过程时,它 return 对我来说是一个数据表,这是预期的结果。
调用 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 接收到 return 值,我在它下面放置了一个断点并且它未达到。 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
当我可以从客户那里从表单中获得价值并且当我团队的其他成员尝试做同样的事情时他们可以调用 SignalR 时,我不知道为什么要这样做也来自不同的方法。
有没有人知道我如何才能完成这项工作?
我知道这已经很长了,但如果我能详细说明,请告诉我
固定代码由于解决方案:
我已将代码从我的 CStatuses 构造函数移动到同一 class 中的新异步方法,并在初始化后调用它。这消除了对 .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);
}
}
您 运行 陷入了 .Result 调用的僵局,我建议在 CStatuses class 中创建一个异步方法,并在您初始化 CStatuses 后 class 调用 websocket用于数据。
我正在开发一个通过 SignalR 客户端执行 SQL 程序的 Winforms 应用程序。我对使用 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 class 中,我的事件处理程序也保存在那里。 (我在这些上有断点,因为我还没有实现它们)
连接处理程序Class
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 客户端中调用过程时,它 return 对我来说是一个数据表,这是预期的结果。 调用 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 接收到 return 值,我在它下面放置了一个断点并且它未达到。 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
当我可以从客户那里从表单中获得价值并且当我团队的其他成员尝试做同样的事情时他们可以调用 SignalR 时,我不知道为什么要这样做也来自不同的方法。
有没有人知道我如何才能完成这项工作?
我知道这已经很长了,但如果我能详细说明,请告诉我
固定代码由于解决方案:
我已将代码从我的 CStatuses 构造函数移动到同一 class 中的新异步方法,并在初始化后调用它。这消除了对 .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);
}
}
您 运行 陷入了 .Result 调用的僵局,我建议在 CStatuses class 中创建一个异步方法,并在您初始化 CStatuses 后 class 调用 websocket用于数据。