InvalidOperation Exception, Background Audio Agent, Windows Phone 8 - windows-phone-8

I'm trying to add a background AudioPlayer to a windows phone 8 application.
I've created the main project and the background audio agent. I've added a reference to the background audio player to the main project, and added the following into the app manifest file.
<ExtendedTask Name="BackgroundTask">
<BackgroundServiceAgent Name="myCastsbackgroundaudio" Type="myCastsbackgroundaudio.AudioPlayer" Source="myCastsbackgroundaudio" Specifier="AudioPlayerAgent"/>
</ExtendedTask>
I've double and triple checked the references and I'm sure they point to the right things.
I'm sharing information between the two applications using IsolatedStorage and the following code
private AudioTrack GetNextTrack()
{
string myTrack = settingsHelper.Read("track", string.Empty);
AudioTrack track = new AudioTrack()
{
Title = "Generic Title",
Source = new Uri("isostore://"+ myTrack, UriKind.Relative)
};
return track;
}
This would appear to pick up the track name fine, and then attempt to create the Audiotrack for playback. At this point, the application will throw the following error.
System.InvalidOperationException was unhandled
_HResult=-2146233079
_message=Operation is not valid due to the current state of the object.
HResult=-2146233079
Message=Operation is not valid due to the current state of the object.
Source=Microsoft.Phone
StackTrace:
at Microsoft.Phone.BackgroundAudio.AudioTrack.set_Title(String value)
at myCastsbackgroundaudio.AudioPlayer.GetNextTrack()
at myCastsbackgroundaudio.AudioPlayer.OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
at Microsoft.Phone.BackgroundAudio.AudioPlayerAgent.CallOnPlayStateChanged(ParameterPropertyBag parameters)
at Microsoft.Phone.BackgroundAudio.AudioPlayerAgent.Invoke(Uri uri, ParameterPropertyBag parameters)
at Microsoft.Phone.BackgroundAgentDispatcher.AgentRequest.Invoke()
at Microsoft.Phone.BackgroundAgentDispatcher.InvocationThread()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
For the life of me, I can't figure what's causing the error. Nothing jumps out as the root cause, and I've done this a couple of times for other apps with no issue.
Any advice or insight is appreciated.
edit: As requested, I have pasted the OnPLayStateChanged code below
protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
{
switch (playState)
{
case PlayState.TrackEnded:
player.Track = GetNextTrack();
break;
case PlayState.TrackReady:
player.Play();
break;
case PlayState.Shutdown:
// TODO: Handle the shutdown state here (e.g. save state)
break;
case PlayState.Unknown:
break;
case PlayState.Stopped:
break;
case PlayState.Paused:
break;
case PlayState.Playing:
break;
case PlayState.BufferingStarted:
break;
case PlayState.BufferingStopped:
break;
case PlayState.Rewinding:
break;
case PlayState.FastForwarding:
break;
}
NotifyComplete();
}
Also to add some additional info, the error is thrown at the creation of the audio track in GetNextTrack, so this code block
AudioTrack track = new AudioTrack()
{
Title = "Generic Title",
Source = new Uri("isostore://"+ myTrack, UriKind.Relative)
};

AudioTrack is very sensitive to edits on the track properties. You should use the constructor to set these values, or else use AudioTrack.BeginEdit/EndEdit.
So try:
var track =
new AudioTrack(
new Uri("isostore://"+ myTrack, UriKind.Relative),
myTrack,
string.Empty,
string.Empty,
null);

Related

How should "Connection reset by peer" be handled in Netty?

A "side effect" of using Netty is that you need to handle stuff you never thought about, like sockets closing and connection resets. A recurring theme is having your logs stuffed full of java.lang.IOException: Connection reset by peer.
What I am wondering about is how to handle these "correctly" from a web server perspective. AFAIK, this error simply means the other side has closed its socket (for instance, if reloading the web page or similar) while a request was sent to the server.
This is how we currently handle exceptions happening in our pipeline (I think it does not make full sense):
s, not the handler I have attached to the end of the pipeline.
current setup
pipeline.addLast(
new HttpServerCodec(),
new HttpObjectAggregator(MAX_CONTENT_LENGTH),
new HttpChunkContentCompressor(),
new ChunkedWriteHandler()
// lots of handlers
// ...
new InterruptingExceptionHandler()
);
pipeline.addFirst(new OutboundExceptionRouter());
the handler of exceptions
private class InterruptingExceptionHandler extends ChannelInboundHandlerAdapter {
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
final var id = ctx.channel().id();
// This needs to ge before the next section as the interrupt handler might shutdown the server before
// we are able to notify the client of the error
ctx.writeAndFlush(serverErrorJSON("A server error happened. Examine the logs for channel id " + id));
if (cause instanceof Error) {
logger.error(format("Error caught at end of pipeline in channel %s, interrupting!", id), cause);
ApplicationPipelineInitializer.this.serverInterruptHook.run();
} else {
logger.error(format("Uncaught user land exception in channel %s for request %s: ", id, requestId(ctx)), cause);
}
}
If some exception, like the IOException, is thrown we try and write a response back. In the case of a closed socket, this will then fail, right? So I guess we should try and detect "connection reset by peer" somehow and just ignore the exception silently to avoid triggering a new issue by writing to a closed socket ... If so, how? Should I try and do err instanceof IOException and err.message.equals("Connection reset by peer") or are there more elegant solutions? To me, it seems like this should be handled by some handler further down in the stack, closer to the HTTP handler
If you wonder about the OutboundExceptionRouter:
/**
* This is the first outbound handler invoked in the pipeline. What it does is add a listener to the
* outbound write promise which will execute future.channel().pipeline().fireExceptionCaught(future.cause())
* when the promise fails.
* The fireExceptionCaught method propagates the exception through the pipeline in the INBOUND direction,
* eventually reaching the ExceptionHandler.
*/
private class OutboundExceptionRouter extends ChannelOutboundHandlerAdapter {
#Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
super.write(ctx, msg, promise);
}
}

Byteman JUnit Runner - impossible to trigger IOException on auto-closed InputStream#close

I have got the following code:
Collection<String> errors = ...;
try (InputStream stream = My.class.getResourceAsStream(resource)) {
// do stuff
}
catch(IOException ex) {
errors.add("Fail");
}
I'm trying with Byteman Junit Runner to trigger an IOException when the (valid) input stream I give is supposedly closed:
#RunWith(BMUnitRunner.class)
public class MyTest {
private My my = new My();
#BMRule(
name = "force_read_error",
targetClass = "java.io.InputStream",
targetMethod = "close()",
action = "throw new IOException(\"bazinga\")"
)
#Test
public void catches_read_error() throws IOException {
Collection<String> errors = my.foo("/valid-resource-in-classpath");
assertThat(errors).containsExactly("Fail");
}
}
My test fails: errors is always empty, which means the Byteman rule obviously isn't executed (it's well loaded by the agent, so I don't understand what's going on).
How can I trigger an IOException on close method called via try-with-resources?
Your rule ist not firing, because the class of the stream object received when calling
InputStream stream = My.class.getResourceAsStream(resource)
is not a "java.io.InputStream" class. It is a class extending "java.io.InputStream", most likely a "BufferedInputStream".
To tell byteman to "trigger rule for any class extending java.io.InputStream", you need to put a '^' before the class name:
targetClass = "^java.io.InputStream"
This change might have the unwanted side effect, that the rule gets triggered also when other objects extending "java.io.InputStream" get closed. To prevent this from happening, a condition should be added to the rule to only get triggered, when the caller matches the "foo" method of the "My" class. Byteman has a helper method for that called "callerMatches" (Please see also the advanced tutorial)
A working condition for your case would be:
condition = "callerMatches(\".+My.foo\",true,true)"
The complete Byteman rule definition as BMRule annotation should look like:
#BMRule(
name = "force_read_error",
targetClass = "^java.io.InputStream",
targetMethod = "close()",
condition = "callerMatches(\".+My.foo\",true,true)",
action = "throw new java.io.IOException(\"bazinga\")"
)

BackgroundUploadAsync Error object not set to an instance

I tried to upload a file to OneDrive. I'm successfully connecting and authenticating to OneDrive but when attempting to upload, I get the error: Object reference not set to an instance of an object.
The code is:
IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
// Release all resources from DB
App.AppViewModel.DisposeCurrentDB();
IsolatedStorageFileStream toUploadStream = iso.OpenFile(AppResources.DatabaseName + ".sdf", FileMode.Open);
LiveConnectClient liveClient = new LiveConnectClient(oneDriveAuthClient.Session);
try
{
LiveOperationResult uploadResult = await liveClient.BackgroundUploadAsync(
oneDriveFolderId,
DatabaseBackupname,
toUploadStream.AsInputStream(),
OverwriteOption.Overwrite);
dynamic result = uploadResult.Result;
MessageBox.Show("Upload successful. Uploaded to " + result.source);
}
catch (LiveConnectException ex)
{
MessageBox.Show("Error uploading backup: " + ex.Message);
}
App.AppViewModel.RefreshCurrentDB();
The BackgroundUploadAysnc method throws the exception. The oneDriveFolderId is set and exists in OneDrive. DatabaseBackupname is a correct new filename which doesn't exist in OneDrive. I checked the stream in debugger and this object was not empty and had a size.
Stacktrace
at Microsoft.Live.Operations.TailoredUploadOperation.<OnGetUploadLinkCompleted>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
I changed the upload code to this:
LiveUploadOperation operation = await liveClient.CreateBackgroundUploadAsync(
oneDriveFolderId,
DatabaseBackupname,
toUploadStream,
OverwriteOption.DoNotOverwrite);
await operation.StartAsync();
and the CreateBackgroundUploadAsync method throws the following exception:
Message = "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
at Windows.Networking.BackgroundTransfer.BackgroundUploader.CreateUploadFromStreamAsync(Uri uri, IInputStream sourceStream)
at Microsoft.Live.Operations.CreateBackgroundUploadOperation.<OnGetUploadLinkCompleted>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
It is not really a solution for the error message, but I changed the Live.SDK reference to the Windows Phone dll and now I can use the BackgroundUploadAsync(path, uri, overwrite) method and it works.
I also had to change the Auth method.
I wasted a few hours on this exact problem. For me it was happening on a Windows Phone 8.0 app that I was migrating to Windows Phone 8.1 Silverlight. What finally resolved things for me was updating to the latest Microsoft Advertising SDK for Windows Phone. I went from version 6.2.960.0 to 8.1.50112.0. As soon as I rebuilt after that, my uploads to OneDrive started to work perfectly. Not at all sure what the root cause was but figured I'd share it here in case it helps anyone.
To be clear, my project file went from this:
<Reference Include="Microsoft.Advertising.Mobile, Version=6.2.960.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Advertising.Mobile.UI, Version=6.2.960.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
to this:
<Reference Include="Microsoft.Advertising.Mobile, Version=8.1.50112.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Advertising.Mobile.Common, Version=8.1.50112.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Advertising.Mobile.UI, Version=8.1.50112.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
I had to "associate" my app "with the Store."
Right-click on the project line in the Solution Explorer in Visual Studio.
Left-click on Store -> Associate App with the Store
I had to sign up as a Microsoft developer (and pay for it), but once I did that, my calls to BackgroundUploadAsync returned reasonable values.
Since it was taking me in the direction I would eventually be going anyway, I figured, What the Heck.

Entity Framework 4.1 - Error in many-to-many relationship data when insert data that removed previously

The scenarios:
3 tables I have which form a Many-to-many relationship:
Agent (AgentID (PK), AgentName)
AgentChannel (AgentID (PK), ChannelID (PK))
Channel (ChannelID (PK), ChannelName)
I do not want to add/delete any record in Agent and Channel tables, but only modify the AgentChannel table.
I am using EF 4.1, POCO and Self-Tracking Entity. All codes that deal with database are include in WCF layer which I calls them server side code, and I only able to control the add/remove of records in client side code.
For example:
I has one Agent record, with multiple Channel records. I able to link existing channel to agent in this way:
var channel = new Channel { ChannelID = 1 };
channel.MarkAsUnchanged();
agent.Channels.Add(channel);
// This will add new entry to AgentChannel table, but no change on Agent and Channel tables
Also I can remove the linkage of a channel to agent in this way:
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == 3);
agent.Channels.Remove(channelToDelete);
// This will remove the entry in AgentChannel, but no change on Agent and Channel tables.
My problem:
If I removed a channel, and add back a new channel which has the same ChannelID with the previously removed channel into agent.Channels collection , I will get this error:
AcceptChanges cannot continue because the object’s key values conflict with another object in the ObjectStateManager.
Sample code to demostrates:
//
// I not able to call ObjectContext here because it was reside in server side.
//
//
// This is client side code
//
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == 3);
// remove channel 3
agent.Channels.Remove(channelToDelete);
var channel = new Channel { ChannelID = 3 };
channel.MarkAsUnchanged();
// Add back channel 3
agent.Channels.Add(channel);
//
// This is server side code (WCF layer)
//
try
{
using (var ctx = new testEntities())
{
ctx.ApplyChanges("Agents", agent); // <-- ERROR happen here
ctx.SaveChanges();
}
}
catch (Exception)
{
throw;
}
then I got thie exception message:
System.InvalidOperationException was unhandled
Message=AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
Source=System.Data.Entity
StackTrace:
at System.Data.Objects.ObjectStateManager.FixupKey(EntityEntry entry)
at System.Data.Objects.EntityEntry.AcceptChanges()
at System.Data.Objects.EntityEntry.ChangeObjectState(EntityState requestedState)
at System.Data.Objects.ObjectStateManager.ChangeObjectState(Object entity, EntityState entityState)
at TestManyToMany.SelfTrackingEntitiesContextExtensions.ChangeEntityStateBasedOnObjectState(ObjectContext context, IObjectWithChangeTracker entity) in F:\MyFile\Development\Temp\TestManyToMany\TestManyToMany\Model1.Context.Extensions.cs:line 728
at TestManyToMany.SelfTrackingEntitiesContextExtensions.HandleEntity(ObjectContext context, EntityIndex entityIndex, RelationshipSet allRelationships, IObjectWithChangeTracker entity) in F:\MyFile\Development\Temp\TestManyToMany\TestManyToMany\Model1.Context.Extensions.cs:line 596
at TestManyToMany.SelfTrackingEntitiesContextExtensions.ApplyChanges[TEntity](ObjectContext context, String entitySetName, TEntity entity) in F:\MyFile\Development\Temp\TestManyToMany\TestManyToMany\Model1.Context.Extensions.cs:line 84
at TestManyToMany.Program.Main(String[] args) in F:\MyFile\Development\Temp\TestManyToMany\TestManyToMany\Program.cs:line 53
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
I hope I make myself clear. This is the only problem I facing now and I run out of idea.
Many thanks.
-
-
Update - Answer
I got the answer after done the testing according to comment from Ladislav Mrnka.
Basically you need to add back to the same entity which removed previously, no other entity because that will gave you the same error above.
Here is the sample code on client side, no changes required in server side:
int channelId = 1;
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == channelId);
// remove channel 1
agent.Channels.Remove(channelToDelete);
//var channel = _allChannels.First(c => c.ChannelID == channelId);
//agent.Channels.Add(channel); <-- This line will give you ERROR because the channel entity is from _allChannels, but not from agent.Channels
// Add back channel 1
agent.Channels.Add(channelToDelete); // <-- This is CORRECT
That is not allowed operation. If you removed channel and you want to add it again you mustn't create a new instance. You must use the old one and only change its state. The main rule is that each entity with unique key must be declared only once. Your code results in two instances with the same key = error.

Operation not permitted on IsolatedStorageFileStream

I'm building this WP7 app that uses a video game API to get the statistics of someone's character (just to help learn silverlight). It grabs the players details from the web service and stores them on isolated storage on the phone to relieve strain from the server.
Originally I had a class which had both the cache writing and reading function, but now i've had to seperate it out into two seperate classes. The cache writing class doesn't matter at the moment, just the cache reading class.
On line 7, it throws an exception saying "Operation not permitted on IsolatedStorageFileStream.", but only during the second time it instantiates the class. I've done some checking with debug and it says the file definately exists, but it stops after the second using clause.
Can anyone help me with this please? I feel like I'm missing something really obvious.
public class CacheReader
{
public PlayerData GetPlayerData(string gamertagIn)
{
using (IsolatedStorageFile CachedReachData = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = CachedReachData.OpenFile(gamertagIn + ".xml", FileMode.Open))
{
Debug.WriteLine("Data Retrieved from cache");
XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
PlayerData loadedPlayer = (PlayerData)serializer.Deserialize(stream);
return loadedPlayer;
}
}
}
}
[EDIT 1]
This is the stack trace i get:
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
at System.IO.IsolatedStorage.IsolatedStorageFile.OpenFile(String path, FileMode mode, FileAccess access)
at ReachPhoneApp.CacheReader.GetPlayerFromCache(String gamertagIn)
at ReachPhoneApp.Page2.GetPlayerData()
at ReachPhoneApp.Page2.cacheWriter_UpdateComplete()
at ReachPhoneApp.CacheWriter.WritePlayerDataToCache(String fileNameIn, Object objectIn)
at ReachPhoneApp.CacheWriter.client_GetGameHistoryCompleted(Object sender, GetGameHistoryCompletedEventArgs e)
at ReachPhoneApp.ReachAPI.ReachApiSoapClient.OnGetGameHistoryCompleted(Object state)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[] args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
Check that you don't somehow have two threads accessing IsolatedStorage at the same time (ie. in VS Debug.View.Threads and verify that at the time of the exception you don't have multiple paths through the same IsoStore code).
This happened in my WP7 code once every few days and was tricky to find, as it seemed to occur only when not connectected to the debugger.
You need to call:
stream.Close();
before
return loadedPlayer;
I think the problem is that you didn't specify that multiple threads could read/write at the same time by specifying a System.IO.FileShare.ReadWrite or whatever access you need as the last parameter of OpenFile.
See the discussion here on the Microsoft Forums.
I ran into this issue as well, but for completely different reasons as mentioned above. I hadn't created the directory that I was saving into.
private void SaveStringDataToStorage(string sDirectory, string sFileName, string sFileContent)
{
string sPath;
//
using (IsolatedStorageFile oFile = solatedStorageFile.GetUserStoreForApplication())
{
if (!oFile.DirectoryExists(sDirectory))
oFile.CreateDirectory(sDirectory);
//
sPath = Path.Combine(sDirectory, sFileName);
//
using (var oWriter = new StreamWriter(new IsolatedStorageFileStream(sPath, FileMode.Create, oFile)))
oWriter.Write(sFileContent);
}
}
Using this code will work if you had the same problem as me, plus it's pretty simple so you can adapt it to whatever you need. I was using this code before I had issues, but I'd forgotten the ! so the directory was never created haha. Just typical. Hope this helps :)
EDIT
Looking closer at the original question, it may be that the file didn't exist. I think it's always best to do IsolatedStorageFile.DirectoryExists() and IsolatedStorageFile.FileExists() before trying to access either location, whether you are reading or writing.
By default when you use IsolatedStorageFile.OpenFile("filename", FileMode.Open) your file gets locked by this thread and no other thread would be able to access this file until 1st thread close it. But if you like to share your file in multiple threads for read purpose only then I would recommend you to use following override
IsolatedStorageFile.OpenFile("filename", FileMode.Open, FileAccess.Read, FileShare.Read)
see details here