Xml Serializer exception not caught in task C# - c#

I have wrote a simple service to serialize and deserialize classes with the default XmlSerializer. I wanted to do this async but when the XMlSerializer throws an exception inside the Task, it is not caught by the try/catch
public async Task<T> DeserializeAsync<T>(TextReader reader)
{
try
{
return await Task.Run(() =>
{
var serializer = new XmlSerializer(typeof(T));
var result = serializer.Deserialize(reader);
return (T) result;
});
}
catch (Exception e)
{
//Do something with exception
}
}
I have one solution but it can't possibly be the solution to this problem:
public async Task<T> DeserializeAsync<T>(TextReader reader)
{
Exception exception = null;
var result = await Task.Run(
() =>
{
try
{
return (T) new XmlSerializer(typeof(T)).Deserialize(reader);
}
catch (Exception e)
{
exception = e;
return default(T);
}
});
if (exception != null)
{
// handle exception
}
return result;
}
UPDATE: Code that reproduces the error:
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
public class Program
{
private static Serializer _serializer;
static void Main(string[] args)
{
_serializer = new Serializer();
Task.Factory.StartNew(ReadUsers);
Console.ReadKey();
}
private static async Task ReadUsers()
{
var stream = new MemoryStream(Encoding.ASCII.GetBytes(""));
try
{
var user = await _serializer.DeserializeAsync<User>(new StreamReader(stream));
Console.WriteLine(user.Name);
}
catch (Exception e)
{
Console.WriteLine($"Caught exception: {e.Message}");
}
}
}
public class Serializer
{
public async Task<T> DeserializeAsync<T>(TextReader reader)
=> await Task.Run(() => (T) new XmlSerializer(typeof(T)).Deserialize(reader));
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}

Related

Multiple asyn calls in same method. The right way?

I need to fetch my public IP address from one of the IP address provider URLs. The catch is that these services are not reliable so I must have fallback to different URLs. To obtain maximum performance, I want to initiate WebRequest to all service providers at the same time and consider the result of the one who replies first.
This is the code i wrote. It works absolutely fine. But I have used EventWaitHandle. I just want to know if this is the right way to do it or is it possible to do the same without using WaitHandle (using async/await only)?
private static readonly string[] IpProviders = new string[] {
"http://ipinfo.io/ip", "http://canihazip.com/s",
"http://icanhazip.com", "http://bot.whatismyipaddress.com" };
private static string _publicIp = null;
public static string PublicIp
{
get
{
if (_publicIp == null)
{
_publicIp = FetchPublicIp();
}
return _publicIp;
}
}
private static string FetchPublicIp()
{
using (MyResetEvent manualEvent = new MyResetEvent())
{
foreach (string providerUrl in IpProviders)
{
FetchPublicIp(providerUrl).
ContinueWith(x => OnResult(x.Result, manualEvent));
}
int looped = 0;
do
{
manualEvent.WaitOne();
lock (manualEvent)
{
if (!string.IsNullOrWhiteSpace(manualEvent.Result))
{
return manualEvent.Result;
}
else
{
manualEvent.Reset();
}
looped = manualEvent.Count;
}
} while (looped < IpProviders.Length);
}
return null;
}
private static async Task<string> FetchPublicIp(string providerUrl)
{
string externalip;
try
{
externalip = await new WebClient().DownloadStringTaskAsync(providerUrl);
}
catch (WebException ex)
{
Debug.WriteLine(ex);
externalip = null;
}
if (!string.IsNullOrWhiteSpace(externalip))
{
System.Net.IPAddress ip;
if (System.Net.IPAddress.TryParse(externalip.Trim(), out ip))
{
return ip.ToString();
}
}
return null;
}
private static void OnResult(string s, MyResetEvent manualEvent)
{
try
{
lock (manualEvent)
{
if (manualEvent.Result == null)
{
manualEvent.Result = s;
}
manualEvent.Count++;
manualEvent.Set();
}
}
catch (ObjectDisposedException ex)
{
Debug.WriteLine(ex);
}
}
Here is the MyResetEvent class:
internal class MyResetEvent : EventWaitHandle
{
public MyResetEvent()
: base(false, EventResetMode.ManualReset)
{
}
public string Result { get; set; }
public int Count { get; set; }
}
You are overthinking this way too much. The TPL is there to help you, not fight you!
async Task<string> TakeFirstResponse(string[] urls)
{
return await await Task.WhenAny(
urls.Select(async url =>
await new WebClient().DownloadStringTaskAsync(url)));
}
Why the double await? The Task.WhenAny returns a Task<Task<T>> by design.
#Bas's answer is right on (you should probably accept it actually), but I wanted to offer an even more terse alternative that uses my Flurl library:
async Task<string> TakeFirstResponse(string[] urls)
{
return await await Task.WhenAny(urls.Select(url => url.GetStringAsync()));
}
Flurl.Http is backed by HttpClient, which is newer and generally preferable to WebClient, all other things being equal.

The App Get Stuck While Trying To serialize an object in metro app

I'm trying to save the animes dictionary in my app which contains string as key and anime as value but when i use the save function the app just get stuck no exception nothing
here is my Anime.cs Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace AnimeTrackerNew
{
[KnownType(typeof(AnimeTrackerNew.Anime))]
[DataContractAttribute]
class Anime:IComparable<Anime>
{
private string name;
private int season;
private int noe;
private int lw;
private Boolean finished;
public Anime(string name)
: base()
{
this.name = name;
}
public Anime(string name,int season, int noe, int lw)
: base()
{
this.name = name;
this.season = season;
this.noe = noe;
this.lw = lw;
if (lw == noe)
finished=true;
else
finished=false;
}
[DataMember]
public string Name
{
get
{
return name;
}
set
{
this.name = value;
}
}
[DataMember]
public int Season
{
get
{
return season;
}
set
{
this.season = value;
}
}
[DataMember]
public int Noe
{
get
{
return noe;
}
set
{
this.noe = value;
}
}
[DataMember]
public int Lw
{
get
{
return lw;
}
set
{
this.lw = value;
}
}
[DataMember]
public Boolean Finished
{
get
{
return finished;
}
set
{
this.finished = value;
}
}
public int CompareTo(Anime other)
{
return this.Name.CompareTo(other.Name);
}
}
}
and these are the save functions
static async public Task Save()
{
await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
{
Sys.SaveAsync().Wait();
}, Windows.System.Threading.WorkItemPriority.Normal);
}
static async public Task Restore<T>()
{
await Windows.System.Threading.ThreadPool.RunAsync((sender) =>
{
Sys.RestoreAsync<T>().Wait();
}, Windows.System.Threading.WorkItemPriority.Normal);
}
static async private Task SaveAsync<T>()
{
StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("animes.xml", CreationCollisionOption.ReplaceExisting);
IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string,Anime>), new Type[] { typeof(T) });
sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), animes);
await sessionOutputStream.FlushAsync();
sessionRandomAccess.Dispose();
}
static async private Task RestoreAsync<T>()
{
StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("animes.xml", CreationCollisionOption.OpenIfExists);
if (sessionFile == null)
{
return;
}
IInputStream sessionInputStream = await sessionFile.OpenReadAsync();
DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(Dictionary<string,Anime>), new Type[] { typeof(T) });
animes = (Dictionary<string, Anime>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead());
}
}
}
after a little debugging it seems the app get stuck on this line
await sessionOutputStream.FlushAsync();
any help with this one would be appriciated:D
Your exception might get swallowed depending on what thread its thrown on, make sure you're set to break on thrown exceptions in visual studio. You can set this on the debug menu > Exceptions > check Thrown on Common Languange Runtime Exceptions
Also, you could eliminate the Save<T>/Restore<T> method and call SaveAsync<T>/RestoreAsync<T> directly, they are both async anyway so Save<T>/Restore<T> is a little redundant. It also creates a unnecessary call to the threadpool.

DRY With Different Try Statements and Identical Catch Statements

So I have the following block of code inside a method: (all variables are local)
// ...
try
{
if (postXml != null)
using (StreamWriter writer = new StreamWriter(req.GetRequestStream()))
writer.Write(postXml.ToString());
}
catch (WebException ex)
{
HttpWebResponse response = ex.Response as HttpWebResponse;
if (response != null)
result = HandleOtherResponse(response, out status);
else result = HandleBadResponse(ex.ToString(), out status);
}
catch (Exception ex)
{
result = HandleBadResponse(ex.ToString(), out status);
}
if (result == null)
{
try
{
HttpWebResponse response = req.GetResponse() as HttpWebResponse;
result = HandleOtherResponse(response, out status);
}
catch (WebException ex)
{
HttpWebResponse response = ex.Response as HttpWebResponse;
if (response != null)
result = HandleOtherResponse(response, out status);
else result = HandleBadResponse(ex.ToString(), out status);
}
catch (Exception ex)
{
result = HandleBadResponse(ex.ToString(), out status);
}
}
// ...
As you can see, the two try statements are different, but the two sets of catch statements are exactly the same. I've been trying to think of a way that it might be possible to not repeat myself here, but I haven't really thought of a way that wouldn't be significantly slower or just as terrible looking. Wondering if anyone has any ideas.
One way would be to write a "safe" invocation method and pass a func to it:
public T SafeInvocation(Func<T> myMethod)
{
T result = default(T);
try
{
// Invoke method
result = myMethod();
}
catch
{
// Do your common catch here
}
return result;
}
Build an additional overload for Action<T> so that you don't need to have a return type. Then you could invoke it elsewhere, passing methods to your method as arguments (Inception?):
SafeInvocation(() =>
{
if (postXml != null)
using (StreamWriter writer = new StreamWriter(req.GetRequestStream()))
writer.Write(postXml.ToString());
}
You could pass an Action into a function that handles the exceptions:
private void HandleErrorsFor(Action action)
{
try
{
action();
}
catch (Exception ex)
{
//repeated exception handling...
{
}
//...
public void DoSomething()
{
HandleErrorsFor(() => {
//try block #1
});
HandleErrorsFor(() => {
//try block #2
});
}
It's a bit easier to read and avoids the repeated code.
You can do something with delegates and cover both try and catch blocks:
static class Program
{
delegate void CodeBlock();
internal delegate void ExceptionCatcher(Exception ex);
private static void Main()
{
CodeBlock b = () => { Console.WriteLine("HELLO WORLD"); };
CodeBlock error = () => { throw new Exception("Exception thrown"); };
ExceptionCatcher silence = exception => { };
ExceptionCatcher e = exception =>
{
var currentColor = Console.BackgroundColor;
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine(exception.Message);
Console.BackgroundColor = currentColor;
};
DRYRunner(b, e);
DRYRunner(error , e);
DRYRunner(error , silence);
Console.ReadLine();
}
static void DRYRunner (CodeBlock block, ExceptionCatcher catcher)
{
try
{
block.Invoke();
}
catch (Exception ex)
{
catcher(ex);
}
}
}
edit: Extending this out, we can create a class to help contain and associate code blocks with their possible exceptions and handlers. You could even create a class of common exception handlers and reference them accordingly, mixing them in with ad-hoc handlers:
class ExceptionHandledDelegate
{
public delegate void CodeBlock();
public delegate void ExceptionCatcher(Exception ex);
public Dictionary<Type, ExceptionCatcher> ExceptionHandlers;
public CodeBlock codeBlock { get; set; }
public void Run()
{
try
{
codeBlock.Invoke();
}
catch (Exception ex)
{
var mn = ex.GetType();
if (ExceptionHandlers.Keys.Contains(mn))
{
ExceptionHandlers[mn](ex);
}
else throw;
}
}
}
class CommonHandlers
{
public static void ArgumentHandler(Exception ex)
{
Console.WriteLine("Handling an argument exception");
}
public static void DivZeroHandler(Exception ex)
{
Console.WriteLine("Please don't divide by zero. It upsets the universe.");
}
}
static class Program
{
private static void Main()
{
var ehd = new ExceptionHandledDelegate
{
codeBlock = () => { throw new ArgumentException("An argument exception has been thrown"); },
ExceptionHandlers = new Dictionary<Type, ExceptionHandledDelegate.ExceptionCatcher>
{
{typeof (ArgumentException), CommonHandlers.ArgumentHandler},
{typeof (DivideByZeroException ),CommonHandlers.DivZeroHandler},
{typeof (Exception), exception => Console.WriteLine("An exception has been thrown")}
}
};
ehd.Run();
ehd.codeBlock = () => { throw new Exception("An exception has been thrown"); };
ehd.Run();
ehd.codeBlock = () =>{var denom = 0; Console.WriteLine(100 / denom);};
ehd.Run();
Console.ReadLine();
}
}

Rx operator to run tasks in series, gathering exceptions at the end

I am using Rx in Silverlight 4 to call my data access code (in absence of place of TPL).
I'd like to make 3 web service calls in series (not parallel for now) and get their results. I used to use SelectMany:
var seq = from a1 in Observable.Return(5).Delay(TimeSpan.FromSeconds(2))
from b1 in Observable.Return(6).Delay(TimeSpan.FromSeconds(2))
from c1 in Observable.Return(7).Delay(TimeSpan.FromSeconds(2))
select new { a1, b1, c1 };
but I'd like the 2nd and third calls to still be performed even if the first has an exception.
Is there an Rx operator that will combine sequences, but only OnException once all its sequences have completed? Something that will be functionally equivalent to the following code:
using System;
using System.Collections.Generic;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
namespace ConsoleApplication4
{
public class Results
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
class Program
{
static void Main(string[] args)
{
new Program().Test();
}
public void Test()
{
GetResults().SubscribeOn(Scheduler.NewThread).Subscribe(
results => Console.WriteLine("{0} {1} {2}", results.A, results.B, results.C),
ex => Console.WriteLine(ex.ToString()),
() => Console.WriteLine("Completed")
);
Console.WriteLine("Not blocking");
Console.Read();
}
public IObservable<Results> GetResults()
{
return Observable.Create<Results>(obs =>
{
var a = Observable.Return(5).Delay(TimeSpan.FromSeconds(2));
var b = Observable.Throw<int>(new Exception("uh oh")).Delay(TimeSpan.FromSeconds(2));
var c = Observable.Return("7").Delay(TimeSpan.FromSeconds(2));
var results = new Results();
var exceptions = new List<Exception>();
try
{
results.A = a.FirstOrDefault();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
results.B = b.FirstOrDefault();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
results.C = c.FirstOrDefault();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
obs.OnNext(results);
if (exceptions.Count > 0)
obs.OnError(new AggregateException(exceptions.ToArray()));
else
obs.OnCompleted();
return Disposable.Empty;
});
}
}
}
How about:
var result = Observable.Concat(
startObservable1().Catch(Observable.Return<TTheType>(null)),
startObservable2().Catch(Observable.Return<TTheType>(null)),
startObservable3().Catch(Observable.Return<TTheType>(null)));
Is there an Rx operator that will combine sequences, but only OnException once all its sequences have completed?
This part is a little harder, I use this class though I'm not super happy with it:
public class Maybe<T>
{
public Exception Exception { get; protected set; }
T _Value;
public T Value {
get {
if (Exception != null) {
throw Exception;
}
return _Value;
}
protected set { _Value = value; }
}
public static Maybe<T> AsError(Exception ex)
{
return new Maybe<T>() {Value = default(T), Exception = ex};
}
public static Maybe<T> AsValue(T value)
{
return new Maybe<T>() {Value = value};
}
}
Then you can do this:
var result = Observable.Concat(
startObservable1().Select(x => Maybe.AsValue(x)).Catch<T1, Exception>(x => Maybe.AsError(x)),
startObservable2().Select(x => Maybe.AsValue(x)).Catch<T1, Exception>(x => Maybe.AsError(x)),
startObservable3().Select(x => Maybe.AsValue(x)).Catch<T1, Exception>(x => Maybe.AsError(x)));
You could probably write your own Maybeify() Extension Method that hides the Select+Catch.

try/catch doesn't work over using statement

try
{
using (response = (HttpWebResponse)request.GetResponse())
// Exception is not caught by outer try!
}
catch (Exception ex)
{
// Log
}
EDIT:
// Code for binding IP address:
ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
servicePoint.BindIPEndPointDelegate = new BindIPEndPoint(Bind);
//
private IPEndPoint Bind(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
IPAddress address;
if (retryCount < 3)
address = IPAddress.Parse("IPAddressHere");
else
{
address = IPAddress.Any;
throw new Exception("IP is not available,"); // This exception is not caught
}
return new IPEndPoint(address, 0);
}
I could imagine this can happen if you are creating a separate thread within the using block. If an exception is thrown there, be sure to handle it there as well. Otherwise, the outer catch block in this case won't be able to handle it.
class TestClass : IDisposable
{
public void GetTest()
{
throw new Exception("Something bad happened"); // handle this
}
public void Dispose()
{
}
}
class Program
{
static void Main(string[] args)
{
try
{
using (TestClass t = new TestClass())
{
Thread ts = new Thread(new ThreadStart(t.GetTest));
ts.Start();
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
Do you have more code after the using? The using needs one statement or a block { } after the using statement. In the example below any exception inside the using statement will be caught with the try..catch block.
try
{
using (response = (HttpWebResponse)request.GetResponse())
{
....
}
}
catch (Exception ex)
{
}
This works fine. You'll see an exception getting printed by the Console.WriteLine()
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
try
{
using (Bar bar = foo.CreateBar())
{
}
}
catch(Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
public class Foo
{
public Bar CreateBar()
{
throw new ApplicationException("Something went wrong.");
}
}
public class Bar : IDisposable
{
public void Dispose()
{
}
}
And if you meant that the exception gets thrown inside the using, this works fine to. This will also generate a Console statement:
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
try
{
using (Bar bar = foo.CreateBar())
{
throw new ApplicationException("Something wrong inside the using.");
}
}
catch(Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
public class Foo
{
public Bar CreateBar()
{
return new Bar();
// throw new ApplicationException("Something went wrong.");
}
}
public class Bar : IDisposable
{
public void Dispose()
{
}
}
The using keyword is the same as try-catch-finally, http://msdn.microsoft.com/en-us/library/yh598w02.aspx. Basically, you have a try-catch-finally nested inside of a try-catch which is why you're probably so confused.
You could just do this instead...
class Program
{
static void Main(string[] args)
{
HttpWebResponse response = new HttpWebResponse();
try
{
response.GetResponse();
}
catch (Exception ex)
{
//do something with the exception
}
finally
{
response.Dispose();
}
}
}

Categories