I have a Windows Phone 7 application that is using Silverlight with C#. This application has a method that fires off multiple web service requests. At another point in my code, I have some code that looks like the following:
myProgressBar.Visibility = Visibility.Visible;
while (AreWebServiceCallsDone() == false)
{
// Need "waiting" code here
}
// Proceed
How do I make my UI "wait" a small amount of time, without locking up the UI, and then check again to see if my web service calls are done?
Thank you!
The answer is to not make the UI wait at all but to "go with the (asynchronous) flow", as it were.
Ultimately, the async stuff in C# 5 will solve this particular problem, but there's no timeline for it's release for the desktop CLR let alone Silverlight or WP7.
I'd personally recommend looking into Microsoft.Phone.Reactive, which is the WP7 version of the Reactive Extensions (Rx) and ships with the SDK. It's a pretty big subject that takes a fair amount of time to get your head around, but can really simplify how you deal with asynchronous scenarios.
Assuming each of your web services return different types of data, I would:
Wrap each web service call in an IObservable1
Use Do to "peek" at the message and perform your side effects (like assigning the value locally)
Use Select to "normalize" the types so that they are all of the same type (required for the next step)
Use ForkJoin to execute each of the requests in parallel and to handle when each has completed
1 Creating an IObservable for your request really depends on how asynchronous pattern you are using. Assuming you're using WebClient, here's an extension method that creates an Observable from DownloadStringAsync as a sample (it may look complex but it's just handling errors and cancellation):
public static class ObservableWebClient
{
public static IObservable<string> DownloadStringObservable(
this WebClient webClient, Uri uri)
{
return Observable.Create(observer =>
{
var disposable = new CompositeDisposable();
var completedObservable = Observable.FromEvent<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs
>(
h => new DownloadStringCompletedEventHandler(h),
h => webClient.DownloadStringCompleted += h,
h => webClient.DownloadStringCompleted h= h
);
disposable.Add(completedObservable
.SelectMany(ev =>
{
return (ev.EventArgs.Error != null)
? Observable.Throw<string>(ev.EventArgs.Error)
: Observable.Return(ev.EventArgs.Result);
})
.Subscribe(observer));
disposable.Add(Disposable.Create(
() => webClient.CancelAsync()));
return disposable;
});
}
}
You can then use it like so:
Note that I've skipped the Do + "normalizing" steps because my data types are all the same (String). As such, I can subscribe to them all as an array (it's a subtlety of how ForkJoin works, if you were wondering)
var webClientA = new WebClient();
var webClientB = new WebClient();
var webClientC = new WebClient();
Observable.ForkJoin(
webClientA.DownloadStringObservable(uriA),
webClientB.DownloadStringObservable(uriB),
webClientC.DownloadStringObservable(uriC),
)
.ObserveOnDispatcher()
.Subscribe(dataArray =>
{
// All three have completed
this.DataA = dataArray[0];
this.DataB = dataArray[1];
this.DataC = dataArray[2];
});
You should be using an async call back method and handle the progress bar's visibility on the call back event.
By using a while, you are making the UI wait for the thread to be executed.
I used this method in my blog post here: http://www.infopoint.com/News-Events/EntryId/29/Building-a-WP7-RSS-reader-Part-1-Basics.aspx
Related
This is my code...
namespaceMyNamespace
{
public class Ping
{
private readonly ILogger<Ping2> _logger;
public Ping2(ILogger<Ping2> log)
{
_logger = log;
}
[FunctionName("Ping2")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "v1/Ping")] HttpRequest req)
{
_logger.LogInformation("Processing: Ping");
if (req.Query["agendaId"] == Microsoft.Extensions.Primitives.StringValues.Empty)
{
return new BadRequestResult();
}
Guid agendaId = Guid.Parse(req.Query["agendaId"]);
string dataTag = "ZZZZ";
string hubName = "myHub";
EventHubProducerClient producerClient;
producerClient = new EventHubProducerClient(connString, hubName);
using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();
MensagemPing data = new MensagemPing() {
ID = Guid.NewGuid(),
agendaId = agendaId,
dataTag = dataTag,
timestamp = DateTime.Now
};
string jsonString = JsonSerializer.Serialize(data);
eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(jsonString)));
await producerClient.SendAsync(eventBatch);
return new OkResult();
}
}
}
I can't find much documentation about the best way to implemment this. Just to start, I will never had a need to send a message in Batch. I found many examples about how to send a single message to the hub, but in mostly case, are deprecated examples or using classic asp.net application.
Also, this endpoint is taking one and a half second to be executed locally, specially because this snippet here take more than 1 second:
EventHubProducerClient producerClient;
producerClient = new EventHubProducerClient(connString, hubName);
using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();
MensagemPing data = new MensagemPing() {
ID = Guid.NewGuid(),
agendaId = agendaId,
dataTag = dataTag,
timestamp = DateTime.Now
};
string jsonString = JsonSerializer.Serialize(data);
eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(jsonString)));
I am pretty convinced that this is not the best practice to consume event hubs. Maybe someone can give me some good example or maybe give me good hists about how to improve it and keep it more faster ?
In this scenario, since you're using Azure Functions, you may want to consider using the Event Hubs output binding rather than using the client library directly. The benefit is that it manages the Event Hubs clients for you, including lifetimes and sending patterns.
If you decide to continue to use the client library directly, there are a few suggestions that I'd make:
The producer is intended to be long-lived; I'd strongly suggest creating it as a singleton, either by registering it via DI using the Microsoft.Extensions.Azure library (preferable) or by creating it as a static member of the class.
If you choose to continue creating the producer in the body of the Function, you'll need to close or dispose it. Otherwise, the connection that it owns will be left open until it idles out after ~20 minutes. This will eventually cause socket exhaustion on the host unless your traffic is really, really low.
Creating an explicit batch for a single event doesn't offer much benefit. I'd suggest using the SendAsync overload that accepts an enumerable instead. For example:
await producer.SendAsync(new[] { eventData }, cancellationToken);
Not impactful, but if you'd like to simplify a bit, there's a constructor overload for EventData that accepts a string; no need to manually perform the encoding:
var eventData = new EventData(jsonString);
If you're dealing with a higher call volume, it may be helpful to consider using the EventHubBufferedProducerClient, as it manages the building of batches and sends implicitly to try and maximize throughput. That said, using in a Functions context is awkward and requires more manual configuration in the Function startup in order to manage its lifetime properly and ensure events are flushed at cleanup. It's probably not worth it unless you're seeing a bottleneck on the single event sends, but there's an end-to-end sample that illustrates using it in an ASP.NET host, which is highly similar to Functions.
I am having the following problem: with RethinkDB using RunChangesAsync method runs once and when used, it starts listening to changes on a given query. When the query changes, you are given the Cursor<Change<Class>> , which is a delta between the initial state and the actual state.
My question is how can I make this run continuously?
If I use:
while(true)
{
code.... //changes happening while program is here
....../
...RunChangesAsync();
/......processed buffered items
code //new changes here
}
If there are changes happening where i pointed in the code, they would not be caught by the RunChanges. The only changes that would be caught would be while RunChanges is listening. Not before ..or after it retrieves the results.
So I tried wrapping the RunChanges in an observable but it does not listen continuously for changes as I would have expected...it just retrieves 2 null items (garbage I suppose) and ends.
Observable
public IObservable<Cursor<Change<UserStatus?>>> GetObservable() =>
r.Db(Constants.DB_NAME).Table(Constants.CLIENT_TABLE).RunChangesAsync<UserStatus?>(this.con,CancellationToken.None).ToObservable();
Observer
class PlayerSubscriber : IObserver<Cursor<Change<UserStatus?>>>
{
public void OnCompleted() => Console.WriteLine("Finished");
public void OnError(Exception error) => Console.WriteLine("error");
public void OnNext(Cursor<Change<UserStatus?>> value)
{
foreach (var item in value.BufferedItems)
Console.WriteLine(item);
}
}
Program
class Program
{
public static RethinkDB r = RethinkDB.R;
public static bool End = false;
static async Task Main(string[] args)
{
var address = new Address { Host = "127.0.0.1", Port = 28015 };
var con = await r.Connection().Hostname(address.Host).Port(address.Port).ConnectAsync();
var database = new Database(r, con);
var obs = database.GetObservable();
var sub = new PlayerSubscriber();
var disp = obs.Subscribe(sub);
Console.ReadKey();
Console.WriteLine("Hello World!");
}
}
When I am debugging as you can see, the OnNext method of the Observer is executed only once (returns two null objects) and then it closes.
P.S: Database is just a wrapper around rethinkdb queries. The only method used is GetObservable which I posted it. The UserStatus is a POCO.
When creating a change feed, you'll want to create one change feed object. For example, when you get back a Cursor<Change<T>> after running .RunChangesAsync(); that is really all you need.
The cursor object you get back from query.RunChangesAsync() is your change feed object that you will use for the entire lifetime you want to receive changes.
In your example:
while(true)
{
code.... //changes happening while program is here
....../
...RunChangesAsync();
/......processed buffered items
code //new changes here
}
Having .RunChangesAsync(); in a while loop is not the correct approach. You don't need to re-run the query again and get another Cursor<Change<T>>. I'll explain how this works at the end of this post.
Also, do not use cursor.BufferedItems on the cursor object. The cursor.BufferedItems property on the cursor is not meant to consumed by your code directly; the cursor.BufferedItems property is only exposed for those special situations where you want to "peek ahead" inside the cursor object (client-side) for items that are ready to be consumed that are specific to your change feed query.
The proper way to consume items in your change feed is to enumerate over the cursor object itself as shown below:
var cursor = await query.RunChangesAsync(conn);
foreach (var item in cursor){
Console.WriteLine(item);
}
When the cursor runs out of items, it will make a request to the RethinkDB server for more items. Keep in mind, each iteration of the foreach loop can be potentially a blocking call. For example, the foreach loop can block indefinitely when 1) there are no items on the client-side to be consumed (.BufferedItems.Count == 0) and 2) there are no items that have been changed on the server-side according to your change feed query criteria. under these circumstances, the foreach loop will block until RethinkDB server sends you an item that is ready to be consumed.
Documentation about using Reactive Extensions and RethinkDB in C#
There is a driver unit test that shows how .NET Reactive Extensions can work here.
Specifically, Lines 31 - 47 in this unit test set up a change feed with Reactive Extensions:
var changes = R.Db(DbName).Table(TableName)
//.changes()[new {include_states = true, include_initial = true}]
.Changes()
.RunChanges<JObject>(conn);
changes.IsFeed.Should().BeTrue();
var observable = changes.ToObservable();
//use a new thread if you want to continue,
//otherwise, subscription will block.
observable.SubscribeOn(NewThreadScheduler.Default)
.Subscribe(
x => OnNext(x),
e => OnError(e),
() => OnCompleted()
);
Additionally, here is a good example and explanation of what happens and how to consume a change feed with C#:
Hope that helps.
Thanks,
Brian
If you have an operation that has the signature Task<int> ReadAsync(), then the way to set up polling, is like this:
IObservable<int> PollRead(TimeSpan interval)
{
return
Observable
.Interval(interval)
.SelectMany(n => Observable.FromAsync(() => ReadAsync()));
}
I'd also caution about you creating your own implementation of IObservable<T> - it's fraught with danger. You should use Observer.Create(...) if you are creating your own observer that you want to hand around. Generally you don't even do that.
I need to test if there's any memory leak in our application and monitor to see if memory usage increases too much while processing the requests.
I'm trying to develop some code to make multiple simultaneous calls to our api/webservice method. This api method is not asynchronous and takes some time to complete its operation.
I've made a lot of research about Tasks, Threads and Parallelism, but so far I had no luck. The problem is, even after trying all the below solutions, the result is always the same, it appears to be processing only two requests at the time.
Tried:
-> Creating tasks inside a simple for loop and starting them with and without setting them with TaskCreationOptions.LongRunning
-> Creating threads inside a simple for loop and starting them with and without high priority
-> Creating a list of actions on a simple for loop and starting them using
Parallel.Foreach(list, options, item => item.Invoke)
-> Running directly inside a Parallel.For loop (below)
-> Running TPL methods with and without Options and TaskScheduler
-> Tried with different values for MaxParallelism and maximum threads
-> Checked this post too, but it didn't help either. (Could I be missing something?)
-> Checked some other posts here in Stackoverflow, but with F# solutions that I don't know how to properly translate them to C#. (I never used F#...)
(Task Scheduler class taken from msdn)
Here's the basic structure that I have:
public class Test
{
Data _data;
String _url;
public Test(Data data, string url)
{
_data = data;
_url = url;
}
public ReturnData Execute()
{
ReturnData returnData;
using(var ws = new WebService())
{
ws.Url = _url;
ws.Timeout = 600000;
var wsReturn = ws.LongRunningMethod(data);
// Basically convert wsReturn to my method return, with some logic if/else etc
}
return returnData;
}
}
sealed class ThreadTaskScheduler : TaskScheduler, IDisposable
{
// The runtime decides how many tasks to create for the given set of iterations, loop options, and scheduler's max concurrency level.
// Tasks will be queued in this collection
private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
// Maintain an array of threads. (Feel free to bump up _n.)
private readonly int _n = 100;
private Thread[] _threads;
public TwoThreadTaskScheduler()
{
_threads = new Thread[_n];
// Create unstarted threads based on the same inline delegate
for (int i = 0; i < _n; i++)
{
_threads[i] = new Thread(() =>
{
// The following loop blocks until items become available in the blocking collection.
// Then one thread is unblocked to consume that item.
foreach (var task in _tasks.GetConsumingEnumerable())
{
TryExecuteTask(task);
}
});
// Start each thread
_threads[i].IsBackground = true;
_threads[i].Start();
}
}
// This method is invoked by the runtime to schedule a task
protected override void QueueTask(Task task)
{
_tasks.Add(task);
}
// The runtime will probe if a task can be executed in the current thread.
// By returning false, we direct all tasks to be queued up.
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
return false;
}
public override int MaximumConcurrencyLevel { get { return _n; } }
protected override IEnumerable<Task> GetScheduledTasks()
{
return _tasks.ToArray();
}
// Dispose is not thread-safe with other members.
// It may only be used when no more tasks will be queued
// to the scheduler. This implementation will block
// until all previously queued tasks have completed.
public void Dispose()
{
if (_threads != null)
{
_tasks.CompleteAdding();
for (int i = 0; i < _n; i++)
{
_threads[i].Join();
_threads[i] = null;
}
_threads = null;
_tasks.Dispose();
_tasks = null;
}
}
}
And the test code itself:
private void button2_Click(object sender, EventArgs e)
{
var maximum = 100;
var options = new ParallelOptions
{
MaxDegreeOfParallelism = 100,
TaskScheduler = new ThreadTaskScheduler()
};
// To prevent UI blocking
Task.Factory.StartNew(() =>
{
Parallel.For(0, maximum, options, i =>
{
var data = new Data();
// Fill data
var test = new Test(data, _url); //_url is pre-defined
var ret = test.Execute();
// Check return and display on screen
var now = DateTime.Now.ToString("HH:mm:ss");
var newText = $"{Environment.NewLine}[{now}] - {ret.ReturnId}) {ret.ReturnDescription}";
AppendTextBox(newText, ref resultTextBox);
}
}
public void AppendTextBox(string value, ref TextBox textBox)
{
if (InvokeRequired)
{
this.Invoke(new ActionRef<string, TextBox>(AppendTextBox), value, textBox);
return;
}
textBox.Text += value;
}
And the result that I get is basically this:
[10:08:56] - (0) OK
[10:08:56] - (0) OK
[10:09:23] - (0) OK
[10:09:23] - (0) OK
[10:09:49] - (0) OK
[10:09:50] - (0) OK
[10:10:15] - (0) OK
[10:10:16] - (0) OK
etc
As far as I know there's no limitation on the server side. I'm relatively new to the Parallel/Multitasking world. Is there any other way to do this? Am I missing something?
(I simplified all the code for clearness and I believe that the provided code is enough to picture the mentioned scenarios. I also didn't post the application code, but it's a simple WinForms screen just to call and show results. If any code is somehow relevant, please let me know, I can edit and post it too.)
Thanks in advance!
EDIT1: I checked on the server logs that it's receiving the requests two by two, so it's indeed something related to sending them, not receiving.
Could it be a network problem/limitation related to how the framework manages the requests/connections? Or something with the network at all (unrelated to .net)?
EDIT2: Forgot to mention, it's a SOAP webservice.
EDIT3: One of the properties that I send (inside data) needs to change for each request.
EDIT4: I noticed that there's always an interval of ~25 secs between each pair of request, if it's relevant.
I would recommend not to reinvent the wheel and just use one of the existing solutions:
Most obvious choice: if your Visual Studio license allows you can use MS Load Testing Framework, most likely you won't even have to write a single line of code: How to: Create a Web Service Test
SoapUI is a free and open source web services testing tool, it has some limited load testing capabilities
If for some reasons SoapUI is not suitable (i.e. you need to run load tests in clustered mode from several hosts or you need more enhanced reporting) you can use Apache JMeter - free and open source multiprotocol load testing tool which supports web services load testing as well.
A good solution to create load tests without write a own project is use this service https://loader.io/targets
It is free for small tests, you can POST Parameters, Header,... and you have a nice reporting.
Isnt the "two requests at a time" the result of the default maxconnection=2 limit on connectionManagement?
<configuration>
<system.net>
<connectionManagement>
<add address = "http://www.contoso.com" maxconnection = "4" />
<add address = "*" maxconnection = "2" />
</connectionManagement>
</system.net>
</configuration>
My favorite load testing library is NBomber. It has an easy and powerful API, realistic user simulations, and provides you with nice HTML reports about latency and requests per second.
I used it to test my API and wrote an article about how I did it.
I have a silverlight 5 app that depends on several asynchronous calls to web services to populate the attributes of newly created graphics. I am trying to find a way to handle those asynchronous calls synchronously. I have tried the suggestions listed in this article and this one. i have tried the many suggestions regarding the Dispatcher object. None have worked well, so I am clearly missing something...
Here is what I have:
public partial class MainPage : UserControl {
AutoResetEvent waitHandle = new AutoResetEvent(false);
private void AssignNewAttributeValuesToSplitPolygons(List<Graphic> splitGraphics)
{
for (int i = 0; i < splitGraphics.Count; i++)
{
Graphic g = splitGraphics[i];
Thread lookupThread1 = new Thread(new ParameterizedThreadStart(SetStateCountyUtm));
lookupThread1.Start(g);
waitHandle.WaitOne();
Thread lookupThread2 = new Thread(new ParameterizedThreadStart(SetCongressionalDistrict));
lookupThread1.Start(g);
waitHandle.WaitOne();
}
private void SetStateCountyUtm(object graphic)
{
this.Dispatcher.BeginInvoke(delegate() {
WrapperSetStateCountyUtm((Graphic)graphic);
});
}
private void WrapperSetStateCountyUtm(Graphic graphic)
{
GISQueryEngine gisQEngine = new GISQueryEngine();
gisQEngine.StateCountyUtmLookupCompletedEvent += new GISQueryEngine.StateCountyUtmLookupEventHandler(gisQEngine_StateCountyUtmLookupCompletedEvent);
gisQEngine.PerformStateCountyUtmQuery(graphic.Geometry, graphic.Attributes["clu_number"].ToString());
}
void gisQEngine_StateCountyUtmLookupCompletedEvent(object sender, StateCountyUtmLookupCompleted stateCountyUtmLookupEventArgs)
{
string fred = stateCountyUtmLookupEventArgs.
waitHandle.Set();
}
}
public class GISQueryEngine
{
public void PerformStateCountyUtmQuery(Geometry inSpatialQueryGeometry, string cluNumber)
{
QueryTask queryTask = new QueryTask(stateandCountyServiceURL);
queryTask.ExecuteCompleted += new EventHandler<QueryEventArgs>(queryTask_StateCountyLookupExecuteCompleted);
queryTask.Failed += new EventHandler<TaskFailedEventArgs>(queryTask_StateCountyLookupFailed);
Query spatialQueryParam = new ESRI.ArcGIS.Client.Tasks.Query();
spatialQueryParam.OutFields.AddRange(new string[] { "*" });
spatialQueryParam.ReturnGeometry = false;
spatialQueryParam.Geometry = inSpatialQueryGeometry;
spatialQueryParam.SpatialRelationship = SpatialRelationship.esriSpatialRelIntersects;
spatialQueryParam.OutSpatialReference = inSpatialQueryGeometry.SpatialReference;
queryTask.ExecuteAsync(spatialQueryParam, cluNumber);
}
//and a whole bunch of other stuff i can add if needed
}
If I leave the 'waitHandle.WaitOne()' method uncommented, no code beyond that method is ever called, at least that I can see with the step through debugger. The application just hangs.
If I comment out the 'waitHandle.WaitOne()', everything runs just fine - except asynchronously. In other words, when the app reads the Attribute values of the new graphics, those values may or may not be set depending on how quickly the asynch methods return.
Thanks for any help.
It's going to be rather difficult to work through a problem like this as there are a few issues you'll need to address. SL is by nature asynch so forcing it to try and work synchronously is usually a very bad idea. You shouldn't do it unless it's absolutely necessary.
Is there a reason that you cannot wait for an async. callback? From what I see you appear to be making two calls for every state that is being rendered. I'm guessing the concern is that one call must complete before the second is made? In scenarios like this, I would kick off the first async call, and in it's response kick off the second call passing along the result you'll want to use from the first call. The second call response updates the provided references.
However, in cases where you've got a significant number of states to update, this results in a rather chatty, and difficult to debug set of calls. I'd really be looking at creating a service call that can accept a set of state references and pass back a data structure set for the values to be updated all in one hit. (or at least grouping them up to one call per state if the batch will be too time consuming and you want to render/interact with visual elements as they load up.)
I'm calling a SSIS package using LoadPackage(...).
Is it possible to make this call an Asynchronous call?
Yes, use an asynchronous delegate, as demostrated here:
http://msdn.microsoft.com/en-us/library/h80ttd5f.aspx
If you just want it to run in the background then yes, you can either spool up a thread or call some T-SQL to dynamically create a job (and remove it again afterwards). If you want to run it asynchronously and want a callback when it's done, then I think you're out of luck unfortunately.
Are you asking if it's 1) legal to call LoadPackage on a background thread or 2) is it possible. For #1 I can't give a definitive answer because I don't use the SSIS framework.
However #2 (as long as #1 is true) is definately doable. IMHO, you're better off using an existing framework which has API's designed to calling API's async and waiting for the results. For instance with Parellel Extensions June 08 CTP, the following code will do.
using System.Threading.Tasks;
...
var future = Future.Create(()=>LoadPackage); // Starts loading the package
// Do other stuff
var package = future.Value; // Wait for package load to complete and get the value
I'm calling an SSIS package from my UI (WPF) via an async WCF service call. Service code is:
public string ImportMarriageXML(bool isWakeUp, bool clearExistingMarriage)
{
try
{
var dts = new Microsoft.SqlServer.Dts.Runtime.Application();
using (var package = dts.LoadFromSqlServer(
ServiceSettings.Settings.SSIS.ImportMarriages,
ServiceSettings.Settings.SSIS.ServerIP,
ServiceSettings.Settings.SSIS.UserID,
ServiceSettings.Settings.SSIS.Password,
null))
{
package.InteractiveMode = false;
package.Connections["DB.STAGING"].ConnectionString = String.Format("{0};Provider={1};", DBSettings.ConnectionString(Core.Database.Staging), ServiceSettings.Settings.SSIS.Provider);
var variables = package.Variables;
variables["IsWakeUp"].Value = isWakeUp;
variables["ClearExistingMarriage"].Value = clearExistingMarriage;
variables["XmlDirectory"].Value = ServiceSettings.Settings.SSIS.Properties.XmlDirectory;
if (package.Execute() == DTSExecResult.Failure)
{
// HACK: Need to refactor this at some point. Will do for now.
var errors = new System.Text.StringBuilder();
foreach (var error in package.Errors)
errors.AppendFormat("SubComponent: {0}; Description: {1}{2}", error.SubComponent, error.Description, Environment.NewLine);
throw new ApplicationException(errors.ToString());
}
return package.Connections["Text Logging"].ConnectionString;
}
}
}
And (part of) the client-side code is as follows:
private void InvokeLoadMarriages()
{
integrationServicesServiceClient.BeginImportMarriageXML(false, OnEndImportMarriageXML, null);
}
private void OnEndImportMarriageXML(IAsyncResult asyncResult)
{
view.InvokeDisplayResults(integrationServicesServiceClient.EndImportMarriageXML(asyncResult));
}
Where BeginImportMarriageXML & EndImportMarriageXML are the generated async operations in the proxy class.