wcfコールバックプログラムがあり、クライアントにメッセージを送信できます。
2番目のメッセージを送信しようとすると、プログラム全体がフリーズし、timeoutexceptionが発生します。
サーバーコードは次のとおりです。
public void SendMessageToClient(string computerName, string message)
{
foreach (var session in connectedClients.Values)
{
if (session.ComputerName == computerName)
{
var asyncResult = session.Callback.BeginOnMessageReceived(message, new AsyncCallback(OnPushMessageComplete), session.Callback);
if (asyncResult.CompletedSynchronously)
CompletePushMessage(asyncResult);
}
}
}
void OnPushMessageComplete(IAsyncResult asyncResult)
{
CompletePushMessage(asyncResult);
}
void CompletePushMessage(IAsyncResult asyncResult)
{
var callbackChannel = (IServiceCallback)asyncResult.AsyncState;
try
{
callbackChannel.EndOnMessageReceived(asyncResult);
}
catch { }
}
そしてこれはCallbackinterfaceです:
[OperationContract(IsOneWay = true, AsyncPattern = true)]
IAsyncResult BeginOnMessageReceived(string message, AsyncCallback acb, object state);
void EndOnMessageReceived(IAsyncResult iar);
そしてこれはクライアントコードです:
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class ServiceHandler : IServiceCallback
{
public delegate void MessageReceivedHandler(string message);
public event MessageReceivedHandler OnMessageReceivedEvent;
public void OnMessageReceived(string message)
{
if (this.OnMessageReceivedEvent != null)
this.OnMessageReceivedEvent(message);
}
}
void callback_OnMessageReceivedEvent(string message)
{
setlb_info(message)
}
public void setlb_info(string wert)
{
if (this.lb_info.InvokeRequired)
{
setlb_infoCallback d = new setlb_infoCallback(setlb_info);
this.Invoke(d, new object[] { wert });
}
else
{
this.lb_info.Text = wert;
}
}
そして私がこれを試してみると:
Service.CurrentInstance.SendMessageToClient(client_name, message);
クライアントはメッセージを受け取りますが、同じメソッドを2回呼び出すと、timeoutexception(1分に設定されています)が表示されます。
私はこのプロジェクト(ドイツ語)のコードを使用しています:
http://www.flexbit.at/blog/wcf-duplex-zwischen-windows-sevice-und-gui-frontend/
この機能が効かないと仕事が終わらないので、誰か助けてくれるといいですね。
よろしくお願いします
編集:クライアント側のコードを忘れました:
var callback = new ServiceHandler();
callback.OnMessageReceivedEvent += new ServiceHandler.MessageReceivedHandler(callback_OnMessageReceivedEvent);
var callbackInstanceContext = new InstanceContext(callback);
client = new ServiceClient(callbackInstanceContext);
client.Subscribe(System.Environment.MachineName);