Невозможно вернуть значение из клиента SignalR из другого метода - PullRequest
0 голосов
/ 25 февраля 2019

Я работаю над приложением 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);
            }
        }

1 Ответ

0 голосов
/ 25 февраля 2019

Вы зашли в тупик при вызове .Result. Я бы предложил создать асинхронный метод в классе CStatuses, а после инициализации класса CStatuses вызвать веб-сокет для данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...