What does DataWriter ObjectDisposedException mean? - c#

The following two lines of code execute one right after the other:
this.dataWriter.WriteBytes(message.MessageBuffer);
await this.dataWriter.StoreAsync();
Although the WriteBytes call completes without exception, the StoreAsync call right below it bombs with a ObjectDisposedException and says
The object has been closed. (Exception from HRESULT: 0x80000013)
this.DataWriter (Windows.Storage.Streams.DataWriter) is not null, so what exactly is it saying is "closed?"
EDIT
Just for some further context on how the object is created
this.socket = new StreamSocketListener();
this.socket.ConnectionReceived += this.EventSocketConnectionReceived;
private void EventSocketConnectionReceived(StreamSocketListener sender,
StreamSocketListenerConnectionReceivedEventArgs args)
{
if (this.dataWriter == null)
{
this.dataWriter = new DataWriter(args.Socket.OutputStream);
}
}

I have no experience with Windows.Storage.Streams.DataWriter, but my bet is that you're passing it a stream, then closing it, then calling this. It's probably not the dataWriter that's even throwing the exception, although glancing at the Stack Trace would tell you.
This code would cause this error, and it's a pretty easy mistake to make:
Windows.Storage.Streams.DataWriter dataWriter;
using (var file = File.OpenRead("..."))
{
dataWriter = new DataWriter(file);
}
dataWriter.WriteBytes(message.MessageBuffer);
await dataWriter.StoreAsync();
Disposal has little to directly do with null. There's rarely much to do with something that's disposed, so we make it null, but that's not necessary.
I'd check around to see what stream you're passing into the constructor, and then look for any references to that stream that might be disposing it (either through a using block like I showed here, or an explicit call to stream.Dispose()).
There are an infinite combination of lines to throw it, and it's unlikely that what you've got is as simple as anything I'm saying here (it's probably spread across constructors and methods, and mixed in with unrelated code). But I'd virtually guarantee that it's something like this pattern.
Just since it sounds like there's some disagreement, the issue here is that it's difficult to tell if something is disposed without telling it to do something.
Because DataWriter is essentially caching up operations, it doesn't talk to the underlying stream until you call StoreAsync(). That's why WriteBytes isn't async, as well. You can imagine an implementation that just pins them onto a List<byte> (although it'd be much more complicated than that, of course).
But when you do call the StoreAsync() method, it reaches out to the stream and says "write this stuff I have cached up." The stream tries, but it's already been closed, so it throws that exception.
That's why it doesn't throw on the first line, but does on the second. And why I'm hazarding the guess that this is a disposed stream, as compared to the DataWriter itself being disposed.
Per your edit and comment, your stream is coming from event args.
My guess is that the stream is getting closed by the event caller, or else the socket is getting closed by the remote client (perhaps due to a timeout?). I don't know whether there's a right way to persist that stream, if it is the former. But that's probably where you should put your research time.

Related

Are sync exceptions possible in HttpClient?

Right now, I'm not talking about ArgumentNullException or InvalidOperationException, but more or less only about HttpRequestException.
var responseAsync = httpClient.SendAsync(something);
try
{
var response = await responseAsync;
}
catch(Exception)
{
}
Will this code ever throw any exceptions, or can we safely assume that all the possible exceptions can only happen during the await?
"but more or less only about HttpRequestException"
MSDN:
The doco makes it quite clear:
HttpRequestException
The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.
So the answer would be "yes" if say your cat pulled out the network lead for example.
Will this code ever throw any exceptions,
Yes.
or can we safely assume that all the possible exceptions can only happen during the await?
It can occur on the following line too because by the time SendAsync returns (not to be confused with when the Task is complete), the Task has already been created and there is a tiny chance of it throwing before you get to the next line.
var responseAsync = httpClient.SendAsync(something);
EDIT: (from my comment below)
Also, for all we know, SendAsync might perform some "initial check" prior to the Task being created. In which case you'll need a try/catch on the above.

ObjectDisposedException for TCPClient.Close in System.dll?

Im using a Request System called xNet and it seems ObjectDisposedExceptions are occuring which on-occurence causes a HUGE cpu spike, sometimes continuously keeping CPU at 99-100% causing freezes and lag.
The script mentioned is the following:
https://github.com/PR4GM4/xNet-Ameliorated
An example code is:
using (HttpRequest httpRequest = new HttpRequest()) {
string url = "https://httpbin.org";
string[] proxysplit = proxy.Split(':');
httpRequest.Proxy = new InternalProxyClient(ProxyType.HTTP, proxysplit[0], int.Parse(proxysplit[1]), null, null);
httpRequest.UserAgent = Http.ChromeUserAgent();
httpRequest.KeepAlive = true;
httpRequest.ConnectTimeout = 15000;
httpRequest.AllowAutoRedirect = true;
HttpResponse hr = httpRequest.Start(HttpMethod.GET, new Uri(url, UriKind.Absolute), new StringContent(""));
if (hr == null) return "2";
string sr = hr.ToString();
if (sr == null) return "2";
}
(If a list of half/dead proxies are needed, I can provide it, just im not sure if linking to them is allowed or not.)
Big note here, it seems to only ever occur whenever theres some kind of other exception like failing to connect to the proxy, or a general bad response, so good connection proxies and/or no proxy at all never has this issue (unless again a general failed error).
If you loop this code, and give it a dead proxy (And to speed things up, multi-thread it to around 5 a time) it will eventually cause an exception like bad response or a timeout and eventually an objectdisposedexception.
I tried debugging in Visual Studio but it gives me almost no information, Historical Debugging gives no information just "Source not found".
Call Stack for the First Exception Thrown of the ObjectDisposedException in the screenshot above.
Seems to be related to line 1430 in ~Http/HttpRequest.cs or line 217 in ~Proxy/ProxyClient.cs as it's the only line I know to exist thats to do with EndConnect socket and also coincidentally can produce ObjectDisposedException. Just not sure how to properly handle the exception here without causing the rest of the script to fail. Also why does a simple exception here cause so much CPU spike?
Strangely enough, no matter how I wrap an exception handler for ObjectDisposedException it never gets triggered, no matter how much code or where I wrap? (On both scripts)
try
{
tcpClient.EndConnect(ar);
}
catch (Exception ex)
{
connectException = ex;
}
I found out why, it wasnt because of the .EndConnect on either of the 2 files, it was actually caused by the .Close() calls, since it does .EndConnect inside of that, thats why I couldnt see any "Source" etc.
So it was causeed because the socket connection wasnt connected, so doing .Close() would cause the Exception.
It was a simple fix.
(Where tcp = a TcpClient)
Do the following instead of just tcp.Close()
On Timeouts (Where it's most likely if never at all connected):
if (tcp.Client.Connected) {
tcp.GetStream().Close();
tcp.Close();
}
When it might be properly connected:
if (!tcp.Connected) {
if (tcp.Client.Connected) tcp.GetStream().Close();
tcp.Close();
}

Handling exceptions thrown by "Dispose" while unwinding nested "using" statements

Apparently, some exceptions may just get lost while using nested using statement. Consider this simple console app:
using System;
namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;
public Throwing(int n)
{
this.n = n;
}
public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}
class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
// this doesn't get called
Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
};
try
{
DoWork();
}
catch (Exception e)
{
// this handles Throwing(1) only
Console.WriteLine("Handle: {0}", e.Message);
}
Console.ReadLine();
}
}
}
Each instance of Throwing throws when it gets disposed of. AppDomain.CurrentDomain.UnhandledException never gets called.
The output:
Throw: Throwing(3)
Throw: Throwing(2)
Throw: Throwing(1)
Handle: Throwing(1)
I prefer to at least be able to log the missing Throwing(2) and Throwing(3). How do I do this, without resorting to a separate try/catch for each using (which would kinda kill the convenience of using)?
In real life, those objects are often instances of classes over which I have no control. They may or may not be throwing, but in case they do, I'd like to have an option to observe such exceptions.
This question came along while I was looking at reducing the level of nested using. There's a neat answer suggesting aggregating exceptions. It's interesting how this is different from the standard behavior of nested using statements.
[EDITED] This question appears to be closely related:
Should you implement IDisposable.Dispose() so that it never throws?
There's a code analyzer warning for this. CA1065, "Do not raise exceptions in unexpected locations". The Dispose() method is on that list. Also a strong warning in the Framework Design Guide, chapter 9.4.1:
AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).
This goes wrong because the using statement calls Dispose() inside a finally block. An exception raised in a finally block can have an unpleasant side-effect, it replaces an active exception if the finally block was called while the stack is being unwound because of an exception. Exactly what you see happening here.
Repro code:
class Program {
static void Main(string[] args) {
try {
try {
throw new Exception("You won't see this");
}
finally {
throw new Exception("You'll see this");
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
What you are noticing is a fundamental problem in the design of Dispose and using, for which no nice solution as yet exists. IMHO the best design would be to have a version of Dispose which receives as an argument any exception which may be pending (or null, if none is pending), and can either log or encapsulate that exception if it needs to throw one of its own. Otherwise, if you have control of both the code which could cause an exception within the using as well as within the Dispose, you may be able to use some sort of outside data channel to let the Dispose know about the inner exception, but that's rather hokey.
It's too bad there's no proper language support for code associated with a finally block (either explicitly, or implicitly via using) to know whether the associated try completed properly and if not, what went wrong. The notion that Dispose should silently fail is IMHO very dangerous and wrongheaded. If an object encapsulates a file which is open for writing, and Dispose closes the file (a common pattern) and the data cannot be written, having the Dispose call return normally would lead the calling code to believe the data was written correctly, potentially allowing it to overwrite the only good backup. Further, if files are supposed to be closed explicitly and calling Dispose without closing a file should be considered an error, that would imply that Dispose should throw an exception if the guarded block would otherwise complete normally, but if the guarded block fails to call Close because an exception occurred first, having Dispose throw an exception would be very unhelpful.
If performance isn't critical, you could write a wrapper method in VB.NET which would accept two delegates (of types Action and an Action<Exception>), call the first within a try block, and then call the second in a finally block with the exception that occurred in the try block (if any). If the wrapper method was written in VB.NET, it could discover and report the exception that occurred without having to catch and rethrow it. Other patterns would be possible as well. Most usages of the wrapper would involve closures, which are icky, but the wrapper could at least achieve proper semantics.
An alternative wrapper design which would avoid closures, but would require that clients use it correctly and would provide little protection against incorrect usage would have a usage batter like:
var dispRes = new DisposeResult();
...
try
{
.. the following could be in some nested routine which took dispRes as a parameter
using (dispWrap = new DisposeWrap(dispRes, ... other disposable resources)
{
...
}
}
catch (...)
{
}
finally
{
}
if (dispRes.Exception != null)
... handle cleanup failures here
The problem with this approach is that there's no way to ensure that anyone will ever evaluate dispRes.Exception. One could use a finalizer to log cases where dispRes gets abandoned without ever having been examined, but there would be no way to distinguish cases where that occurred because an exception kicked code out beyond the if test, or because the programmer simply forgot the check.
PS--Another case where Dispose really should know whether exceptions occur is when IDisposable objects are used to wrap locks or other scopes where an object's invariants may temporarily be invalidated but are expected to be restored before code leaves the scope. If an exception occurs, code should often have no expectation of resolving the exception, but should nonetheless take action based upon it, leaving the lock neither held nor released but rather invalidated, so that any present or future attempt to acquire it will throw an exception. If there are no future attempts to acquire the lock or other resource, the fact that it is invalid should not disrupt system operation. If the resource is critically necessary to some part of the program, invalidating it will cause that part of the program to die while minimizing the damage it does to anything else. The only way I know to really implement this case with nice semantics is to use icky closures. Otherwise, the only alternative is to require explicit invalidate/validate calls and hope that any return statements within the part of the code where the resource is invalid are preceded by calls to validate.
Maybe some helper function that let you write code similar to using:
void UsingAndLog<T>(Func<T> creator, Action<T> action) where T:IDisposabe
{
T item = creator();
try
{
action(item);
}
finally
{
try { item.Dispose();}
catch(Exception ex)
{
// Log/pick which one to throw.
}
}
}
UsingAndLog(() => new FileStream(...), item =>
{
//code that you'd write inside using
item.Write(...);
});
Note that I'd probably not go this route and just let exceptions from Dispose to overwrite my exceptions from code inside normal using. If library throws from Dispose against strong recommendations not to do so there is a very good chance that it is not the only issue and usefulness of such library need to be reconsidered.

Better way to read in stream data without wrapping the whole thing in an empty try catch?

Doing something like this at the moment:
try
{
while ((bytesRead = clientStream.Read(data, 0, data.Length)) != 0)
{
string message = Encoding.ASCII.GetString(data, 0, bytesRead) + Environment.NewLine;
txtLog.Invoke(c => c.AppendText(message));
}
}
catch
{
}
Which works but it's pretty ugly.
I know people are going to say not to catch all exceptions and to at least do something when an exception occurs but I'm writing a server application. If a user abruptly disconnections it doesn't matter. It doesn't need to be logged. Also, I never want the program to crash so is catching all exceptions really that bad? The program can still recover. After the while loop this code executes and everything is fine. Right?:
string clientIdentifier = tcpClient.Client.RemoteEndPoint.ToString();
bool clientRemoved = clients.TryRemove(clientIdentifier);
if (clientRemoved)
{
listUsers.Invoke(c => c.Items.Remove(clientIdentifier));
}
tcpClient.Close();
Not really asking a specific question but more of wondering if this is fine and if not, what is a better way to handle a user abruptly disconnecting or any other form of read error?
Not really asking a specific question but more of wondering if this is fine and if not, what is a better way to handle a user abruptly disconnecting or any other form of read error?
Catch IOException and leave the others uncaught (the others indicate bugs in your code, and you don't want to swallow them). The Exception.InnerException tells you what happened, and, if the inner exception is a SocketException, you can check the SocketException.ErrorCode to get specific detail.
Note also that you can check NetworkStream.CanRead to see if the stream is readable (yes, the user could abruptly close after NetworkStream.CanRead returns true but before you execute the read). You should still wrap the NetworkStream.Read in a try/catch but note that you can avoid the exception if NetworkStream.CanRead is false.
Instead of Try, catch block, you can use Using block. But hey you cant get exception inside a using block though unless you explicitly use try catch again.
Catching exception isnt really bad, but doing nothing and swallowing is bad.
But, as per your code, please use finally block to close all your objects streams rather than just living with catch. so that your app is safe and sound.

Error occurs while trying to write an image in to Isolated Storage in WP7 Mango

Here i am attaching the code snippet.
Error is: An error occurred while accessing IsolatedStorage.
public Boolean SaveImage(string filename, WriteableBitmap wrtbmp)
{
try
{
using (IsolatedStorageFile iSF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (iSF.FileExists(filename))
{
iSF.DeleteFile(filename);
}
using (IsolatedStorageFileStream fstream = new IsolatedStorageFileStream(filename, FileMode.CreateNew, FileAccess.Write, iSF))
{
wrtbmp.SaveJpeg(fstream, wrtbmp.PixelWidth, wrtbmp.PixelHeight, 0, 100);
fstream.Close();
fstream.Dispose();
}
}
}
catch (Exception ex)
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
return false;
}
return true;
}
This is the method i am using for saving Image, while executing when it reaches the portion of deleting the file if it already exists, it throws the error, but in some cases it executes perfectly without an error.
The stacktrace points to the DeleteFile. Are you sure the path-to-delete is valid? Are you sure that the file exists? I don't remember well, but I think the Delete file might throw if the file is not found - please check the example in the linked MSDN method description - they have an IF-exists there.
[EDIT: I'm sorry, I'm quite a bit tired today and I didn't read through your code properly. Obviously you have your code already guarded against file-nonexistence.]
Aside from the possible nonexistence problem, there is also a small possibility that ont here, but somewhere else in your code, there is something that has opened the file and did not close it properly. In such case, the system will think the file is in use (even if that "old" handle opened elsewhere is "forgotten" and wait to be GC'ed) and no operations on that file will succeed unles that handle actually dies.
Another thing is, that even with your using/autodispose, the operation can still fail if you try to invoke the method multiple times at once from different threads. With async patterns, it sometimes can be hard to notice - check thoroughly from what points of code this method is called and think whether it may happen ie. that at the same time GUI callback will invoke it, and maybe also some background operation? If so, try to wrap the using additionally with a lock-statement. If this helps, that means you have reentrancy problems.
edit: someone, at some point in distant future, will kill me for hundrets of edits.. but I'll write it anyways:) : I think that in general, you do not have to delete the file before writing to it. The CreateFile is not the only one to get access to the files. Check OpenFile with mode=OpenOrCreate|Truncate or even shorter: mode=Create (see FileMode flags for explanation)
First of all, there's no reason to call fstream.Close(); and fstream.Dispose(); when you're using a using statement, which automatically closes and disposes of the stream.
Secondly, your error isn't explicit enough.

Categories