Conversion to Parallel/TPL for this Async code - wcf

I'm wondering as to how I'd go aroung converting this Begin-End-Async approach to the newer TPL syntax:
public override IAsyncResult BeginRegisterClaimant(ClaimantSex claimantSex, AgeGroup ageGroup, AsyncCallback callback, object state)
{
AsyncResult<string> asyncResult = new AsyncResult<string>(callback, state);
InitManagementProxy();
m_management.RegisterClaimantCompleted += RegisterClaimantCallbackInternal;
m_management.RegisterClaimantAsync(m_configurationID, (PowWow.Service.ClaimantSex)claimantSex, (PowWow.Service.AgeGroup)ageGroup, new object[]
{ this, asyncResult
});
return asyncResult;
}
public override string EndRegisterClaimant(IAsyncResult asyncResult)
{
if (!(asyncResult is AsyncResult<string>))
{
throw new Exception("Invalid IAsyncResult object");
}
return ((AsyncResult<string>)asyncResult).Close();
}
private void InitManagementProxy()
{
WSHttpBinding binding;
if (m_management != null)
{
return;
}
binding = new WSHttpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
m_management = new PowWow.Service.VerifierContractClient(binding, new EndpointAddress(m_managementUri));
m_management.ClientCredentials.UserName.UserName = m_userName;
m_management.ClientCredentials.UserName.Password = m_password;
}
private static void RegisterClaimantCallbackInternal(object senderObject, PowWow.Service.RegisterClaimantCompletedEventArgs eventArgs)
{
PowWowVerifier powWowVerifier = (PowWowVerifier)((Object[])eventArgs.UserState)[0];
powWowVerifier.m_management.RegisterClaimantCompleted -= RegisterClaimantCallbackInternal;
powWowVerifier.m_management.Close();
powWowVerifier.m_management = null;
if (eventArgs.Error != null)
{
((AsyncResult<string>)((Object[])eventArgs.UserState)[1]).OnException(eventArgs.Error);
}
else
{
((AsyncResult<string>)((Object[])eventArgs.UserState)[1]).OnExecuted(eventArgs.Result);
}
}
Thanks!
EDIT
ATM, cancellation is not required. Progress reporting maybe required but not a priority.

The simplest way would be to wrap your existing code in a TaskCompletionSource and return it's Task - this will then fit in with the new async/await model coming in C# 5

Related

PushStreamContent in asp.net core - video start playing only when whole file is buffered

i have problem with PushStreamContent in asp.net core.
It display video on the website but my problem is that it will buffer whole file and then play it when my goal is to buffer small part of it and play on the website. Code i have:
My endpoint for playing video in browser
public IActionResult Play(string file)
{
var fileName = "C:\\repo\\trailer1.mp4";
var video = new VideoStream(fileName);
var response = new PushStreamContent(video.WriteToStream, new MediaTypeHeaderValue("video/mp4"))
{
};
var objectResult = new ObjectResult(response);
objectResult.ContentTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("video/mp4"));
return objectResult;
}
Ive got VideoStreamClass to help with displaying video
public class VideoStream
{
private readonly string _filename;
public VideoStream(string filename)
{
_filename = #"C:\\repo\\trailer1.mp4";
}
public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[65536];
using (var video = File.Open(_filename, FileMode.Open, FileAccess.Read))
{
var length = (int)video.Length;
var bytesRead = 1;
while (length > 0 && bytesRead > 0)
{
bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length));
await outputStream.WriteAsync(buffer, 0, bytesRead);
await outputStream.FlushAsync();
length -= bytesRead;
}
}
}
catch (Exception)
{ return; }
finally
{
outputStream.Dispose();
}
}
}
And here is my VideoOutputFormatter added to bootstraper
public class VideoOutputFormatter : IOutputFormatter
{
public bool CanWriteResult(OutputFormatterCanWriteContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (context.Object is PushStreamContent)
return true;
return false;
}
public async Task WriteAsync(OutputFormatterWriteContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
using (var stream = ((PushStreamContent)context.Object))
{
var response = context.HttpContext.Response;
if (context.ContentType != null)
{
response.ContentType = context.ContentType.ToString();
}
await stream.CopyToAsync(response.Body);
}
}
}
I've tried to add atributes to controller "UseBufferedOutputStream" and "UseBufferedInputStream" setted to false but this still dosent work for me
ObjectResult is intended for holding an in-memory object as a response. If you want to return an existing file, then PhysicalFileResult is probably your best bet.
If you're interested in PushStreamContent, I believe the one you're using is for HttpClient, not ASP.NET. If you want a PushStreamContent equivalent, I have a FileCallbackResult that would work once it's updated for the latest .NET Core.

org.apache.fop.fo.flow.ExternalGraphic catches and logs ImageException I want to handle myself

I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.

VCR for ServiceStack's JsonServiceClient

The Ruby VCR library enables you to "Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests."
I'd like to create something similar using ServiceStack's JsonServiceClient, but I can't get it to work. My most recent failed attempt follows. I'd like to either make my current attempt work, or suggestions on another approach that will work.
public static class Memoization
{
public static Func<T, TResult> AsCached<T, TResult>(this Func<T, TResult> function)
{
var cachedResults = new Dictionary<T, TResult>();
string filename = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + (typeof(TResult)).Name + ".jsv";
var serializer = MessagePackSerializer.Create<Dictionary<T, TResult>>();
if (cachedResults.Count == 0)
{
////// load cache from file
using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
cachedResults = serializer.Unpack(fs);
}
}
return (argument) =>
{
TResult result;
lock (cachedResults)
{
if (!cachedResults.TryGetValue(argument, out result))
{
result = function(argument);
cachedResults.Add(argument, result);
////// update cache file
using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
serializer.Pack(fs, cachedResults);
}
}
}
return result;
};
}
}
class MemoizeJsonClient<TResponse> : JsonServiceClient, IServiceClient, IRestClient
{
private Func<IReturn<TResponse>, TResponse> _getCached;
private JsonServiceClient client;
public TResponse Get(IReturn<TResponse> request)
{
if (_getCached == null)
{
Func<IReturn<TResponse>, TResponse> func = GetImpl;
_getCached = func.AsCached();
}
return _getCached(request);
}
private TResponse GetImpl(IReturn<TResponse> request)
{
return client.Get(request);
}
public MemoizeJsonClient(string BaseUri) {
client = new JsonServiceClient(BaseUri);
}
}
Called like this:
[Test]
public void TestReports2()
{
string Host = "http://localhost:1337";
string BaseUri = Host + "/";
List<Options> testcases = new List<Options>();
testcases.Add(new Options("Name", "20130815", "20130815"));
foreach (Options options in testcases)
{
TransactionsReq transRequest = new TransactionsReq();
transRequest.source = "Source";
transRequest.name = new List<String>(new string[] { options.Name });
transRequest.startDate = options.StartDate;
transRequest.endDate = options.EndDate;
MemoizeJsonClient<TransactionsReqResponse> client = new MemoizeJsonClient<TransactionsReqResponse>(BaseUri);
List<Transaction> transactions;
TransactionsReqResponse transResponse = client.Get(transRequest);
transactions = transResponse.data;
}
}
But I get the following error:
System.Runtime.Serialization.SerializationException occurred
HResult=-2146233076
Message=Cannot serialize type 'ServiceStack.ServiceHost.IReturn`1[ImagineServerWrapper.DTO.TransactionsReqResponse]' because it does not have any serializable fields nor properties.
Source=MsgPack
StackTrace:
at MsgPack.Serialization.SerializerBuilder`1.CreateSerializer()
InnerException:

How to dynamically bind event to command in WinRT without Reactive framework?

I'm implementing modified version of Behavior for my Windows 8 app according to this guide. It works except one place where the Reactive framework is required:
protected override void OnAttached()
{
var evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
Observable.FromEventPattern<RoutedEventArgs>(AssociatedObject, Event)
.Subscribe(se => FireCommand());
}
base.OnAttached();
}
The question is simple, how to achieve similar funcitonality without the Reactive frmaework? I've browsed the source of of Rx that can be obtained here, but I'ts just too complicated to me.
I've also succeeded porting to code with the only problem that it work only for fixed type of EventHandler:
protected override void OnAttached()
{
EventInfo evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
AssignEvent<ItemClickEventHandler>(AssociatedObject, Event, FireCommand);
}
base.OnAttached();
}
protected void AssignEvent<T1>(object instance, string eventName, T1 handler)
{
EventInfo runtimeEvent = instance.GetType().GetRuntimeEvent(eventName);
Func<T1, EventRegistrationToken> add = a => (EventRegistrationToken)runtimeEvent.AddMethod.Invoke(instance, new object[] { a });
Action<EventRegistrationToken> remove = a => runtimeEvent.RemoveMethod.Invoke(runtimeEvent, new object[] { a });
WindowsRuntimeMarshal.AddEventHandler(add, remove, handler);
}
Any idea, how to make it dynamic so I don't have to use specific event handler "ItemClickEventHandler"? Note in classic .NET it' quite simple, but in WinRT I cannot use Delegate.CreateDelegate(...)
Update:
Thanks to Brandon I was able to finish the method, it now looks like this:
protected override void OnAttached()
{
EventInfo evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
MethodInfo addMethod = evt.AddMethod;
MethodInfo removeMethod = evt.RemoveMethod;
ParameterInfo[] addParameters = addMethod.GetParameters();
Type delegateType = addParameters[0].ParameterType;
Action<object, object> handler = (s, e) => FireCommand(e as RoutedEventArgs);
MethodInfo handlerInvoke = typeof(Action<object, object>).GetRuntimeMethod("Invoke", new[] { typeof(object), typeof(object) });
Delegate #delegate = handlerInvoke.CreateDelegate(delegateType, handler);
Func<object, EventRegistrationToken> add = a => (EventRegistrationToken)addMethod.Invoke(AssociatedObject, new object[] { #delegate });
Action<EventRegistrationToken> remove = t => removeMethod.Invoke(AssociatedObject, new object[] { t });
WindowsRuntimeMarshal.AddEventHandler(add, remove, handler);
}
base.OnAttached();
}
Now I can remove 800kB of Rx dlls, thanks again!
I trolled through the Rx source, and here is the important bit of functionality:
MethodInfo addMethod = eventInfo.GetAddMethod();
MethodInfo removeMethod = eventInfo.GetRemoveMethod();
var addParameters = addMethod.GetParameters();
var delegateType = addParameters[0].ParameterType;
Action<object, object> handler = (object sender, object eventArgs) => FireCommand();
MethodInfo handlerInvoke = typeof(Action<object, object>).GetMethod("Invoke");
Delegate delegate = handlerInvoke.CreateDelegate(delegateType, handler);
Func<EventRegistrationToken> add = a => (EventRegistrationToken)addMethod.Invoke(instance, new object[] { delegate });
Action<EventRegistrationToken> remove = t => removeMethod.Invoke(instance, new object[] { t });
It looks like the important info is they are using MethodInfo.CreateDelegate.

.NET CF WebService ObjectDisposedException

I am trying to solve an issue with one of my Smart Device projects (.NET CF 3.5 on Windows Mobile 6.5 Device).
The code tries to make webservice calls continuously to get some data and use it in the form. During the usage, for a particular case is an ObjectDisposedException thrown and the application crashes. The stacktrace is
System.ObjectDisposedException was unhandled
Message="ObjectDisposedException"
ObjectName=""
StackTrace:
at System.Threading.Timer.throwIfDisposed()
at System.Threading.Timer.Change(UInt32 dueTime, UInt32 period)
at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
at System.Net.HttpWebRequest.startReadWriteTimer()
at System.Net.HttpWebRequest.ConnectionClient.Read(Byte[] data, Int32 offset, Int32 length)
at System.Net.HttpReadStream.NetworkRead(Byte[] data, Int32 offset, Int32 length)
at System.Net.ChunkedReadStream.fillBuffer()
at System.Net.ChunkedReadStream.getLine()
at System.Net.ChunkedReadStream.doRead(Byte[] data, Int32 offset, Int32 length)
at System.Net.HttpReadStream.ReadToDrain(Byte[] buffer, Int32 offset, Int32 length)
at System.Net.HttpReadStream.doClose()
at System.Net.HttpReadStream.Finalize()
I have read many blogs and forums, including this, and the solution suggested seems to be to close the request stream and the request, before getting the response.
requestStream = webRequest.GetRequestStream();
requestStream.Close(); // WE NEED THIS LINE in order to avoid the ObjectDisposedException.
But this does not help my situation. If the requestStream is closed before writing to the data to the stream then it does not do anything. If I close after getting the response, then it throws InvalidOperationException.
Following is my code:
Reference.cs
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="ProductResolveServiceSOAP11Binding", Namespace="urn:ProductResolveService")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Exception))]
public partial class ProductResolveService : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public ProductResolveService() {
this.Url = "http://172.26.37.115:8080/axis/services/ProductResolveService";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:getResolvedEpcs", RequestNamespace="http://services.axis.oatsystems.com", ResponseNamespace="http://services.axis.oatsystems.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("return", IsNullable=true)]
public ResolvedProductList getResolvedEpcs([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] EpcToResolve message) {
object[] results = this.Invoke("getResolvedEpcs", new object[] {
message});
return ((ResolvedProductList)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BegingetResolvedEpcs(EpcToResolve message, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("getResolvedEpcs", new object[] {
message}, callback, asyncState);
}
/// <remarks/>
public ResolvedProductList EndgetResolvedEpcs(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((ResolvedProductList)(results[0]));
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Web.Services.Protocols;
using System.Windows.Forms;
using NFEHandlingProject.StatusService;
using System.IO;
using MVProductResolveService;
namespace NFEHandlingProject
{
public partial class Form1 : Form
{
private Thread resolveThread;
int counter = 0;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (resolveThread == null)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Creating Thread"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
resolveThread = new Thread(new ThreadStart(GetEpcProductMapping));
resolveThread.IsBackground = true;
resolveThread.Priority = ThreadPriority.BelowNormal;
resolveThread.Start();
}
}
object syncRoot2 = new object();
bool resolving = false;
private void GetEpcProductMapping()
{
lock (syncRoot2)
{
if (resolving)
{
return;
}
resolving = true;
}
while (resolving)
{
using (ProductResolveService2 productResolveService = new ProductResolveService2())
{
EpcToResolve epcToResolve = null;
try
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Resolving..."); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
productResolveService.Url = "http://172.26.37.115:8080/axis/services/ProductResolveService?wsdl";
productResolveService.Timeout = 60000;
// The input object that is sent to xpress
epcToResolve = new EpcToResolve();
string epcBase = "3410402AEA0000000000";
int baseDec = Convert.ToInt32("1000", 16);
// Creating the input of epc's baed on the ResolveBatchSize and number epcs's that needs to be resolved at xpress
string[] epcs = new string[1];
for (int i = 0; i < 1; i++)
{
int epcDec = baseDec + i;
epcs[i] = epcBase + epcDec.ToString("X");
}
// setting the epc list which is the input that is sent to xpress
epcToResolve.epcList = epcs;
//pass the flag to check if say whether the productInformation or just the product_id is resolved
epcToResolve.returnOnlyProductId = false;
//return productResolveService.getResolvedEpcs(epcToResolve);
productResolveService.getResolvedEpcs(epcToResolve);
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolved"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (SoapHeaderException)
{
// do nothing
}
catch (SoapException se)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Problem resolving products at xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (WebException we)
{
// get the reason for the exception
WebExceptionStatus status = we.Status;
String description = we.Message;
WebResponse response = we.Response;
if (response != null)
{
Stream respStream = response.GetResponseStream();
if (respStream != null)
{
respStream.Close();
respStream.Dispose();
respStream = null;
}
// close the response
response.Close();
response = null;
}
// Case when there is no connectivity. Just display an error message to the user to indicate that there is no connectivity.
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: There is no connectivity to xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
catch (ThreadAbortException)
{
// Do nothing. Do not log
}
catch (System.Exception e)
{
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("An exception occured when fetching data from xpress"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
try
{
Thread.Sleep(200);
}
catch
{
}
}
}
resolving = false;
}
private void btnStop_Click(object sender, EventArgs e)
{
if (resolveThread != null && resolving)
{
resolveThread.Abort();
resolveThread.Join();
resolveThread = null;
resolving = false;
this.BeginInvoke((Action)delegate { lstbxStatusMsgs.Items.Add("Resolve Product: Stopped Thread"); lstbxStatusMsgs.SelectedIndex = lstbxStatusMsgs.Items.Count - 1; });
}
}
}
}
On clicking on the Start Button in the form, the thread is created and keeping calling the webservice, when the stop is called, the thread is stopped. Repeated start and stop causes the ObjectDisposedException (that is how I reproduced this exception).
Any help on this regard will be highly appreciated, as I have been trying to solve this issue for a few days now.
Thanks
Senthil
This is a pretty old post. However, I wanted to record my answer here for any body who is still looking for an answer.
Two options:
Move to WCF Clients which is much easier and cleaner.
Use the below solution.
public class ExtendedDataImport : DataImport.DataImport
{
private WebRequest webRequest;
private WebResponse webResponse;
/// <summary>
/// This method overrides the generated method and sets parameters so that HTTP 1.0
/// is used (without chunking). If left with default parameters it
/// sometimes fails.
/// </summary>
protected override WebRequest GetWebRequest(Uri uri)
{
webRequest = base.GetWebRequest(uri);
((HttpWebRequest)webRequest).KeepAlive = false;
((HttpWebRequest)webRequest).ProtocolVersion = HttpVersion.Version10;
return webRequest;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
webResponse = base.GetWebResponse(request);
return webResponse;
}
public void Close()
{
if (webResponse != null)
{
Stream responseStream = webResponse.GetResponseStream();
responseStream.Close();
responseStream.Dispose();
responseStream = null;
webResponse.Close();
webResponse = null;
}
if (webRequest != null)
{
// Aborting the WebRequest, cleans up the webrequest and
// stops the timer which causes the ObjectDisposedException
try
{
webRequest.Abort();
webRequest = null;
}
catch (ObjectDisposedException ex)
{
// Ignoring the object disposed exception as mentioned in the follwoing link
//http://social.msdn.microsoft.com/Forums/en/netfxcompact/thread/8f21514c-9b7c-40d3-96c9-794c0dc167fe
}
}
}
protected override void Dispose(bool disposing)
{
Close();
base.Dispose(disposing);
}
}