Я работаю над приложением Winforms, которое выполняет процедуры SQL через клиент SignalR.Я относительно новичок в использовании 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 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, он возвращает мне 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
Я в недоумении, почему это такделая это, когда я могу получить значение от клиента из формы и когда другие члены моей команды пытались сделать то же самое, они могут сделать вызов SignalR также из другого метода.
Кто-нибудь имееткакие-нибудь идеи относительно того, как я могу сделать эту работу?
Я понимаю, что это стало довольно долго, но если я могу уточнить детали, пожалуйста, дайте мне знать
FIXED CODE СПАСИБОДЛЯ РЕШЕНИЯ: Я переместил код из моего конструктора 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);
}
}