【问题标题】:C# How to force the wait for the connection to a WCF serviceC#如何强制等待连接到 WCF 服务
【发布时间】:2018-06-01 00:53:58
【问题描述】:

我有一个作为本地 SYSTEM 运行的服务,它使用用户凭据启动另一个应用程序。 第二个应用程序只是一个托盘图标,它使用回调方法接收到的字符串向用户显示气球提示。第二个应用程序以双工模式连接到 WCF。

我的问题是,由于某种原因,与 WCF 的连接在 Main 方法结束时完成。所以我不能在执行后立即向应用程序发送回调消息,包含在最后一行“kiosk.MyStart(args);”中。回调仍然指向 null。

知道如何解决这个问题吗?

static void Main(string []args)
{
    if (Environment.UserInteractive)
    {
         // Start the WCf service
         var host = new ServiceHost(typeof(WcfService));
         host.Open();

         //Launch the Kiosk Agent which connects to the WCF
         bool ret = ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");
         WinService kiosk = new WinService(args);
         // some checks and a welcome message is sent to the user.
         kiosk.MyStart(args);

         //...
         //...
    }
}

编辑:再澄清一点,在 kiosk.MyStart 方法内部,我尝试执行回调以显示欢迎消息,但回调仍然为 NULL。 结果,我假设客户端由于任何原因没有正确启动,我再次启动它......

            if (WcfService.Callback != null)
                WcfService.Callback.UIMessageOnCallback(UIMessage);
            else
                ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");

【问题讨论】:

  • 我不明白你在问什么,也不明白 WCF 在哪里涉及到 kiosk.MyStart 方法。你显示的代码是什么?那是服务吗?从哪里得到什么东西是空的?那么什么是 null 呢? args 还是 kiosk?这真的需要minimal reproducible example
  • 依靠 Windows 服务成功启动 GUI 应用程序是个坏主意。如果没有用户登录怎么办?也许考虑具有仅在登录时运行限制的 Windows 任务管理器?
  • @rene,当我尝试调用回调时,我在 Kiosk.mystart 方法中得到了它。请参阅我在帖子中添加的注释。
  • @MickyD 你是对的,这就是为什么我还实施了检查是否有用户登录。如果没有用户登录,我不会尝试查找托盘图标进程向其发送任何消息。
  • @jacortijo 启动客户端应用程序您也可以使用所有用户的启动文件夹%programdata%\Microsoft\Windows\Start Menu\Programs\Startup在此文件夹中添加 kioskAgent 的快捷方式create-shortcut-on-desktop-c-sharp

标签: c# multithreading wcf


【解决方案1】:

在回调方法上添加一个 try catch 块,如果客户端无法访问它,则可以取消订阅它。向您的客户发送一条 keepalive 消息以检查它是否可用也是一种很好的做法。

private void InformClient(ClientInfo clientInfo)
{
    var subscribers = this._subscriberRepository.GetAll();
    foreach (var subscriber in subscribers)
    {
        try
        {
            if (subscriber.Callback.FireInformClient(clientInfo));
            {
                //If subscriber not reachable, unsubscribe it
                this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            }
        }
        catch (Exception exception)
        {
            //If subscriber not reachable, unsubscribe it
            this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            Log.Error(nameof(InformClient), exception);
        }
    }
}

IClientCallback

public interface IClientCallback
{
    [OperationContract]
    bool FireInformClient(ClientInfo clientInfo);
}

如果您有更多订阅者,例如一个终端,服务器创建一个订阅者存储库来管理所有订阅者。

var callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();
if (this._subscriberRepository.Subscribe(clientId, callback))
{
    return true;
}

【讨论】:

    猜你喜欢
    • 2011-03-11
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 2015-02-13
    • 2023-01-30
    • 1970-01-01
    相关资源
    最近更新 更多