WCF не работает внутри класса формы

Я следовал этому руководству по основам межпроцессного взаимодействия WCF: http://tech.pro/tutorial/855/wcf-tutorial-basic-interprocess-communication

У меня есть клиент и сервер, которые работают как консольные приложения (как создается в учебнике).

Но когда я переместил код сервера WCF в свою форму, он не работает.

Код сервера консольного приложения (отлично работает как консольное приложение):

[ServiceContract]
public interface IModelData
{
    [OperationContract]
    ArrayList GetData();
}

public class ModelDataServer : IModelData
{
    public ArrayList GetData()
    {
        return new ArrayList(); // Just for testing that it works (before form version)
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost host = new ServiceHost(
        typeof(ModelDataServer),
        new Uri[]{
            new Uri("http://localhost:8000")
        }))
        {
            host.AddServiceEndpoint(typeof(IModelData),
                new BasicHttpBinding(),
                "ModelData");

            host.Open();

            Console.WriteLine("Service is available. " +
                "Press <ENTER> to exit.");
            Console.ReadLine();

            host.Close();
        }
    }
}

Я читал, что возникает проблема с формами WCF и Windows, если вы запускаете ServiceHost в потоке пользовательского интерфейса. запуск WCF в формах Windows ‹это говорит мне, что я могу исправить проблему с помощью UseSynchronizationContext = false, как показано ниже, но у меня все еще возникают проблемы.

Мой код формы:

public partial class ServerForm : Form
{
    ModelDataServer Server;
    public ScraperForm()
    {
        InitializeComponent();

        Server = new ModelDataServer(); // this should start the server?
    }

// other stuff
}

[ServiceContract]
public interface IModelData
{
    [OperationContract]
    ArrayList GetData();
}

[ServiceBehavior(UseSynchronizationContext=false)]
public class ModelDataServer : IModelData
{
    ServiceHost Host;
    public ModelDataServer()
    {
        using (ServiceHost Host = new ServiceHost(
        typeof(ModelDataServer),
        new Uri[]{
          new Uri("http://localhost:8000")
        }))
        {
            Host.AddServiceEndpoint(typeof(IModelData),
              new BasicHttpBinding(),
              "ModelData");

            Host.Open();
        }
    }

    public ArrayList GetData()
    {
        return GetData();
    }

    public void CloseServer()
    {
        Host.Close();
    }
}

Я не верю, что мой хост собирает мусор в приведенном выше примере, потому что это поле. Я прав?

Ошибка, которую я получаю при вызове этого сервера из моего клиента (работая с указанным выше консольным приложением), выглядит следующим образом:

There was no endpoint listening at http://localhost:8000/ModelData that could accept
the message. This is often caused by an incorrect address or SOAP action. See
InnerException, if present, for more details.

Спасибо за вашу помощь.


person janderson    schedule 15.12.2013    source источник
comment
Покажите свой код web.config   -  person Atish Dipongkor    schedule 15.12.2013


Ответы (1)


using (ServiceHost Host = new ServiceHost(
    typeof(ModelDataServer),
    new Uri[]{
      new Uri("http://localhost:8000")
    }))
    {
        Host.AddServiceEndpoint(typeof(IModelData),
          new BasicHttpBinding(),
          "ModelData");

        Host.Open();
    }

Вы открываете свой сервисный хост внутри блока using. После оператора Host.Open(); ничего нет, поэтому ваш блок using завершается, а хост закрывается. Следовательно, ни одна конечная точка не слушает.

Было бы лучше (в этом случае) пропустить блок using и явно открывать и закрывать узел службы. Вы должны иметь возможность подключиться к одному из событий завершения приложения, чтобы закрыть узел при выходе из приложения.

person Tim    schedule 15.12.2013
comment
Поскольку я сделал Host полем класса, я подумал, что он не будет удален после использования. Спасибо. - person janderson; 15.12.2013