Es gibt ein Framework und Tutorial zur Verfügung, das scheint, dieses Problem recht gut zu behandeln WPF Service Host on Codeplex.
BEARBEITEN: Aktualisiert, um die Technik zu veranschaulichen, die von der WPF-Service-Host-Vorlage erstellt wurde.
Der WPF-Diensthost ist eine Vorlage für Visual Studio, mit der eine Skelettanwendung und ein Testclient erstellt werden. Ich werde die relevanten Stücke hier beschreiben.
Hier ist, was das Skelett Projekt wie folgt aussieht:
ClientServiceHost.cs
using System;
using System.ServiceModel;
namespace WPFServiceHost1.Service
{
public class ClientServiceHost : IDisposable
{
private bool _Initalized;
private ServiceHost _InnerServiceHost;
private MainWindow _MainWindow;
public ClientServiceHost(MainWindow mainWindow)
{
_MainWindow = mainWindow;
InitializeServiceHost();
}
private void InitializeServiceHost()
{
try
{
ClientService clientService = new ClientService(_MainWindow);
_InnerServiceHost = new ServiceHost(clientService);
_InnerServiceHost.Opened += new EventHandler(_InnerServiceHost_Opened);
_InnerServiceHost.Faulted += new EventHandler(_InnerServiceHost_Faulted);
_InnerServiceHost.Open();
}
catch (Exception ex)
{
throw new Exception("Unable to initialize ClientServiceHost", ex);
}
}
void _InnerServiceHost_Opened(object sender, EventArgs e)
{
_Initalized = true;
}
void _InnerServiceHost_Faulted(object sender, EventArgs e)
{
this._InnerServiceHost.Abort();
if (_Initalized)
{
_Initalized = false;
InitializeServiceHost();
}
}
#region IDisposable Members
public void Dispose()
{
try
{
_InnerServiceHost.Opened -= _InnerServiceHost_Opened;
_InnerServiceHost.Faulted -= _InnerServiceHost_Faulted;
_InnerServiceHost.Close();
}
catch
{
try { _InnerServiceHost.Abort(); }
catch { }
}
}
#endregion
}
}
MainWindow.xaml
<Window x:Class="WPFServiceHost1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPFServiceHost1" Height="344" Width="343" Closing="Window_Closing">
<Grid>
<Label Height="28" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="119">Messages received:</Label>
<ListBox Margin="21,38,26,21" Name="listBox1" />
</Grid>
</Window>
MainWindow.xaml.cs
IClientService.cs
using System.ServiceModel;
namespace WPFServiceHost1.Service
{
[ServiceContract(Namespace = "urn:WPFServiceHost")]
public interface IClientService
{
[OperationContract]
void ClientNotification(string message);
}
}
ClientService.cs
using System;
using System.ServiceModel;
namespace WPFServiceHost1.Service
{
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
public class ClientService : IClientService
{
private MainWindow _MainWindow;
public ClientService(MainWindow window)
{
_MainWindow = window;
}
#region IClientService Members
public void ClientNotification(string message)
{
try
{
_MainWindow._SyncContext.Send(state =>
{
_MainWindow.listBox1.Items.Add(message);
}, null);
}
catch (Exception ex)
{
throw new FaultException(ex.Message);
}
}
#endregion
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ClientServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ClientServiceBehavior"
name="WPFServiceHost1.Service.ClientService">
<endpoint address="ClientService" binding="basicHttpBinding" contract="WPFServiceHost1.Service.IClientService"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8010" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Und die Testclient, Program.cs:
using System;
using System.ServiceModel;
using System.Threading;
namespace TestClient
{
class Program
{
static void Main(string[] args)
{
IClientService proxy = null;
try
{
proxy = ChannelFactory<IClientService>.CreateChannel(new BasicHttpBinding(), new EndpointAddress("http://localhost:8010/ClientService"));
Console.WriteLine("Press <Enter> when ClientService is running.");
Console.ReadLine();
Console.WriteLine();
Console.WriteLine("Sending a single message to ClientService");
proxy.ClientNotification("Hello from TestClient");
Console.WriteLine();
Console.Write("Enter a valid number to load test ClientService: ");
string result = Console.ReadLine();
int testCount = Convert.ToInt32(result);
int counter = 0;
object counterLock = new object();
while (true)
{
lock (counterLock)
{
Thread t = new Thread(() => proxy.ClientNotification(string.Format("Load test from TestClient: {0}", ++counter)));
t.Start();
}
if (counter == testCount)
break;
}
Console.ReadLine();
}
finally
{
ICommunicationObject co = proxy as ICommunicationObject;
try
{
co.Close();
}
catch { co.Abort(); }
}
Console.ReadLine();
}
}
}
In diesem Fall wird Ihr Service Singleton sein. –