Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WCF Duplex in Winforms Question

262 views
Skip to first unread message

Jeff

unread,
Mar 26, 2008, 11:57:01 AM3/26/08
to
I still have a lot to learn about WCF and I am hoping someone can point me in
the right direction. I am using the wsDualHttpBinding binding to implement a
publisher subscriber model. I have 3 projects set up in a solution - the
host, a Console client, and a Winforms client.

The Console client works as expected. But the Winforms client hangs when
calls the method to publish data.

If I run multiple instances of the winforms client the other instances get
their callbacks. But the one that publishes the data hangs. It never returns
from the Trade() method, which is the contract method I created to publish
stock trades in this example. I am sure this is related to me not
understanding something about the threading or instancing being used by WCF
and how it relates to the GUI thread.

I couldn't see a way to attach the source so I stuck in on a website here:
http://www.suddethassoc.com/DuplexMethod.zip

Any help would be appreciated.

Jeff

Jeff

unread,
Mar 27, 2008, 4:31:01 PM3/27/08
to
I have a solution and I thought I would post it in case anyone is interested.

First is that the class that implements the callback on the client needs the
CallbackBehavior attribute with the UseSynchronizationContext option turned
off. In other words:

[CallbackBehavior(UseSynchronizationContext = false)]
class Client : ITradeServiceCallback
{
private Form1 _frm;

public Client(Form1 frm)
{
_frm = frm;
}

public void OnTrade(string symbol, int ticks)
{
SendOrPostCallback addTradeDel = delegate
{
_frm.AddTrade(symbol, ticks);
};

_frm._context.Post(addTradeDel, null);
}
}

Notice in there that I store a reference to the form. This is because the
Form will store the SynchronizationContext for its GUI thread when it is
created. When my OnTrade method is invoked I tell that form's
SynchronizationContext to call a method using a delegate.

You can see in this code snippet where I grab the SynchronizationContext in
the form's constructor.

public partial class Form1 : Form
{
private Client c;
TradeServiceClient client;

// this will be called by the callback client so make it public
public SynchronizationContext _context;

public Form1()
{
InitializeComponent();

_context = SynchronizationContext.Current;

// create the callback object
c = new Client(this);
InstanceContext site = new InstanceContext(null, c);

// create the proxy object
client = new TradeServiceClient(site);

//create a unique callback address so multiple clients can run
on one machine
WSDualHttpBinding binding =
(WSDualHttpBinding)client.Endpoint.Binding;
string clientcallbackaddress =
binding.ClientBaseAddress.AbsoluteUri;
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);

//Subscribe.
client.Subscribe();
}


Before I was using the Form's Invoke method to update the GUI. I thought
that would let the UI thread do its work. But it was blocking. This way
works. Now I have to see if I can figure out why this is the case. But at
least I have a working example.

That code would probably be cleaner if I used my form class as the callback
implementation but for whatever reason I decided to keep them seperate.

I posted the solution at the following URL if anyone cares.
http://www.suddethassoc.com/DuplexMethodhttp.zip

I want to give credit to the folks at iDesign. It was by going through their
samples that I was able to figure this out.

coder...@gmail.com

unread,
May 31, 2014, 8:05:53 AM5/31/14
to
Yes.

i do care.

This had me pulling some hairs out!

Thanks for taking the time to share your discoveries. You have taken considerable time off of my research.

Much appreciated!
0 new messages