I am getting a lot of files that are not being uploaded to my AWS bucket but it the code below always shows complete. Anyone know whats up with this? How am I supposed to find out if the upload failed or not if it always comes back complete? I did see something about using transferutility.EndUpload but I am unsure on how to use it. Also how would I implement a retry? Pass the object state to BeginUpload? Any help?
public class S3Upload
{
private string awsAccessKeyId = "XXXXXX";
private string awsSecretAccessKey = "XXXXXX";
private string bucketName = System.Configuration.ConfigurationManager.AppSettings.Get("BucketName");
private Amazon.S3.Transfer.TransferUtility transferUtility;
private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public S3Upload()
{
// Initialize log4net.
log4net.Config.XmlConfigurator.Configure();
this.transferUtility = new Amazon.S3.Transfer.TransferUtility(awsAccessKeyId, awsSecretAccessKey);
log.Info("S3 instance initiated");
}
public void UploadFile(string filePath, string toPath)
{
try
{
AsyncCallback callback = new AsyncCallback(uploadComplete);
log.Info("S3 upload started...");
log.InfoFormat("S3 filePath: {0}", filePath);
log.InfoFormat("S3 toPath: {0}", toPath);
var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
uploadRequest.FilePath = filePath;
uploadRequest.BucketName = bucketName;
uploadRequest.Key = toPath;
uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
uploadRequest.AddHeader("x-amz-acl", "public-read");
transferUtility.BeginUpload(uploadRequest, callback, null);
}
catch (AmazonS3Exception amazonS3Exception)
{
log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);
}
}
private void uploadComplete(IAsyncResult result)
{
var x = result;
if (x.IsCompleted)
{
log.Info("S3 upload completed...");
}
}
}
Found a fix! I added transferUtility.EndUpload(ar) and if it error's it will write the exception to my log and retry the put request.
Error making request PutObject.
System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. --->
public class S3Upload
{
private string awsAccessKeyId = "XXXXX";
private string awsSecretAccessKey = "XXXXX";
private string bucketName = System.Configuration.ConfigurationManager.AppSettings.Get("BucketName");
private Amazon.S3.Transfer.TransferUtility transferUtility;
private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public S3Upload()
{
// Initialize log4net.
log4net.Config.XmlConfigurator.Configure();
this.transferUtility = new Amazon.S3.Transfer.TransferUtility(awsAccessKeyId, awsSecretAccessKey);
log.Info("S3 instance initiated");
}
public void UploadFile(string filePath, string toPath)
{
try
{
AsyncCallback callback = new AsyncCallback(uploadComplete);
log.Info("S3 upload started...");
log.InfoFormat("S3 filePath: {0}", filePath);
log.InfoFormat("S3 toPath: {0}", toPath);
var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
uploadRequest.FilePath = filePath;
uploadRequest.BucketName = bucketName;
uploadRequest.Key = toPath;
uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
uploadRequest.AddHeader("x-amz-acl", "public-read");
IAsyncResult ar = transferUtility.BeginUpload(uploadRequest, callback, null);
transferUtility.EndUpload(ar);
}
catch (AmazonS3Exception amazonS3Exception)
{
log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);
}
}
private void uploadComplete(IAsyncResult result)
{
var x = result;
}
}
The BeginUpload function starts a new thread that initiates and performs the upload. Calling EndUpload causes the current thread to block until the upload is complete. Also, the EndUpload function catches any exceptions that you'll get from the upload.
If you're going to call BeginUpload, you need to call EndUpload() from a separate thread so that you're not blocking your main thread. If you plan on blocking your main thread, just call the Upload() function instead of the APM versions.
For example, spawn a new thread that will sit and wait for the upload to complete. (Note that it doesn't have to do anything specific, just catch the errors.)
public void UploadFile(string filePath, string toPath)
{
try
{
AsyncCallback callback = new AsyncCallback(uploadComplete);
log.Info("S3 upload started...");
log.InfoFormat("S3 filePath: {0}", filePath);
log.InfoFormat("S3 toPath: {0}", toPath);
var uploadRequest = new Amazon.S3.Transfer.TransferUtilityUploadRequest();
uploadRequest.FilePath = filePath;
uploadRequest.BucketName = bucketName;
uploadRequest.Key = toPath;
uploadRequest.StorageClass = Amazon.S3.Model.S3StorageClass.ReducedRedundancy;
uploadRequest.AddHeader("x-amz-acl", "public-read");
IAsyncResult ar = transferUtility.BeginUpload(uploadRequest, callback, null);
// transferUtility.EndUpload(ar);
ThreadPool.QueueUserWorkItem(c =>
{
try
{
transferUtility.EndUpload(ar);
}
catch (AmazonS3Exception ex)
{
// Retry, log the error, etc.
}
catch (WebException ex)
{
// Retry, log the error, etc.
}
});
}
catch (AmazonS3Exception amazonS3Exception)
{
log.ErrorFormat("An Error, number {0}, occurred when creating a bucket with the message '{1}", amazonS3Exception.ErrorCode, amazonS3Exception.Message);
}
}
Also, that thread checks for WebException. I don't know if you can get one of these from the Beginupload or not, but some code I'm working on seems to watch for those. (Better safe then sorry.)
Also, I found you can test this with the CurrPorts Utility. That utility lets you kill the open port to amazon (although it will retry up until its configured MaxRetries).
Related
In the ClientClass, I have two threads; one for TCP-IP connection to a localhost and another to keep receiving messages from the localhost.
In case the connection gets broken, I close the connection using m_DeviceClientSocket.Close() inside the catch block of the method ConnectToDeviceAndMonitorConnection().
PROBLEM: Since I close the socket connection, therefore, the whole m_DeviceClientSocket object is dereferenced. This leads to another error inside the catch block of the method GetMessagesFromDevice() and the error says (as shown in the catch block of the code):
"Cannot access a disposed object.\r\nObject name:
'System.Net.Sockets.NetworkStream'
QUESTION: How should I create the m_DeviceClientSocket object, which can be closed, reconnected and is available to both the threads?
class ClientClass
{
Thread t1_DeviceConnectionMonitor, t2_receiveDeviceMessages;
static readonly object m_IsConnectedToDevice_Locker = new object();
bool m_IsConnectedToDevice = false;
//Device - Communication Variables
string m_DeviceURL = "127.0.0.1";
int m_DevicePort = 23;
TcpClient m_DeviceClientSocket = new TcpClient();
NetworkStream m_DeviceServerStream = default(NetworkStream);
public ClientClass()
{
//Thread for CONNECTION Monitoring
t1_DeviceConnectionMonitor = new Thread(ConnectToDeviceAndMonitorConnection);
t_DeviceConnectionMonitor.Start();
//Thread to RECEIVE messages
t2_receiveDeviceMessages = new Thread(GetMessagesFromDevice);
t2_receiveDeviceMessages.Start();
}
//Connect to Device
void ConnectToDeviceAndMonitorConnection()
{
while (true)
{
if (!m_IsConnectedToDevice)
{
try
{
//Connect to device server
m_DeviceClientSocket.Connect(m_DeviceURL, m_DevicePort);
m_DeviceServerStream = m_DeviceClientSocket.GetStream();
SetDeviceConnectionStatus(true);
}
catch (SocketException se)
{
if (m_DeviceClientSocket.Connected)
m_DeviceClientSocket.Close(); //This Close() statement dereference the complete "m_DeviceClientSocket" object
}
}
}
}
//RECEIVE messages from the device
public void GetMessagesFromDevice()
{
string messageReceivedFromDevice;
while (true)
{
try
{
var buffersize = m_DeviceClientSocket.ReceiveBufferSize;
byte[] instream = new byte[buffersize];
int status = m_DeviceServerStream.Read(instream, 0, buffersize);
if (status == 0)
{
SetDeviceConnectionStatus(false);
}
messageReceivedFromDevice = System.Text.Encoding.ASCII.GetString(instream);
}
catch (Exception e)
{
//I ENETER HERE AND THE EXCEPTIONS SAYS: ""Cannot access a disposed object.\r\nObject name: 'System.Net.Sockets.NetworkStream'"
}
}
}
//Thread Safety is needed to set the device connection status
public void SetDeviceConnectionStatus(bool status)
{
lock (m_IsConnectedToDevice_Locker)
{
m_IsConnectedToDevice = status;
}
}
}
I am using this code to monitor creation of files in certain folder:
_watcher = new RecoveringFileSystemWatcher(SourceFolder, "*.xml");
_watcher.Created += (_, e) =>
{
ProcessFile(e.Name);
};
RecoveringFileSystemWatcher is a fileSystemWatcher wrapper. It's constructor is:
public RecoveringFileSystemWatcher (string path, string filter)
{
_containedFSW = new FileSystemWatcher(path, filter);
}
The process works as expected but for some files, randomly, an exception is thrown telling that the file is used by another process.
This is the method that is launched upon file creation:
var nfo = new FileInfo(filePath);
if (nfo.Exists)
{
var archivoXml = nfo.Name;
string archivo = String.Empty;
try
{
string content = Task.Run(async () => await GetFileContent(filePath)).Result;
if (String.IsNullOrEmpty(content))
return false;
XmlDocument xml = new XmlDocument();
xml.LoadXml(content);
//The rest of the method
}
}
the method GetFileContent is this:
private async Task<string> GetFileContent(string filePath)
{
string content = String.Empty;
try
{
Console.Write("ONE - "); InfoLog.Save($"ONE {filePath}");
using (StreamReader sr = new StreamReader(filePath))
{
Console.Write("TWO - "); InfoLog.Save($"TWO {filePath}");
content = await sr.ReadToEndAsync().ConfigureAwait(false);
Console.Write($"THREE {(sr.BaseStream == null ? "Closed" : "Opened")} - "); InfoLog.Save($"THREE {(sr.BaseStream == null ? "Closed" : "Opened")} {filePath}");
sr.Close();
Console.WriteLine($"FOUR {(sr.BaseStream == null ? "Closed" : "Opened")}"); InfoLog.Save($"FOUR {(sr.BaseStream == null ? "Closed" : "Opened")} {filePath}");
}
}
catch (Exception ex)
{
InfoLog.Save($"XML file could be read -> {filePath}. See error log.");
ErrorLog.Save(ex);
}
return content;
}
Look at the log information I am writing to debug the process.
I got one case with a file called 1112186.xml.... this is recorded in the log:
18/12/2018 19:12:10 ONE D:\GestorDocumental\Origen\1112186.xml
18/12/2018 19:12:10 XML file could not be read -> D:\GestorDocumental\Origen\1112186.xml. See error log.
As you see, the exception is thrown at the "using" instruction.
If I see the full log, I can see that file, 1112186.xml, is never used before, so the only chance is that FSW keeps the file opened. I don't know why, but it seems this is happening.
It is clear also that this process is locking the file, because when I exit the console application and then run again, the file can be processed.
Any help about this, please?
thanks
Jaime
I usually use this method to check if file is locked. I got it from one of the link in stackoverflow.
public static bool IsFileClosed(string filepath)
{
bool fileClosed = false;
int retries = 20;
const int delay = 400; // set a delay period = retries*delay milliseconds
if (!File.Exists(filepath))
return false;
do
{
try
{
// Attempts to open then close the file in RW mode, denying other users to place any locks.
FileStream fs = File.Open(filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
fs.Close();
fileClosed = true; // success
}
catch (IOException) { }
retries--;
if (!fileClosed)
Thread.Sleep(delay);
}
while (!fileClosed && retries > 0);
return fileClosed;
}
This is a new class called FileTimerWatcher (it will have logger injected):
public FileTimerWatcher(ILogger logger) : base(logger)
{
if (timer == null)
{
// Create a timer with a 1.5 second interval.
// monitor the files after 1.5 seconds.
timer = new Timer(delay);
// Hook up the event handler for the Elapsed event.
timer.Elapsed += new ElapsedEventHandler(ProcessFolder);
timer.AutoReset = true;
timer.Enabled = true;
}
}
private void ProcessFolder(object sender, ElapsedEventArgs e)
{
var LastChecked = DateTime.Now;
string[] files = System.IO.Directory.GetFiles(SourceDirectory, somefilter, System.IO.SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
ProcessFile(file); // process file here
}
}
Disclaimer: My C# isn't even close to as good as my C++
I am trying to learn how to do async sockets in C# in order to write a test app for a component of mine. I read about a variety of methods, but it seems the most modern is to use TcpClient, get the NetworkStream from it, and call async methods on the NetworkStream that return Task.
So, I set off on my adventure.
It is not clear how to cancel the async methods properly or if I need to. Am I supposed to manually cancel them when I want to disconnect? One would think TcpClient.Close would take care of that in some graceful way for me.
If I do use the manual cancellation, then it seems there is some mechanism needed to wait until all the async methods exit before the main thread continues on. Noted in the listing in the Disconnect() method. The result is that the main thread continues on disposing and exiting before MakeRequest() or Read() have exited, and therefore exceptions about using disposed objects.
In my test without manual cancellation, I get the same exception from the async read, about using an object that has been disposed, because the main thread still continues on disposing and exiting before those methods are exited.
I suppose I could put in my own synchronization mechanism...but what is the proper way to do this? Should I be cancelling at all? Is there some built in way to wait for those methods to exit? What did they expect us to do?
Here is my latest code attempt:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using log4net;
using System.IO;
using System.Threading;
namespace IntegrationTests
{
public class Client
{
private static readonly ILog log = LogManager.GetLogger("root");
static private ulong m_lastId = 1;
private ulong m_id;
private string m_host;
private uint m_port;
private uint m_timeoutMilliseconds;
private string m_clientId;
private TcpClient m_tcpClient;
private CancellationTokenSource m_cancelationSource;
public Client(string host, uint port, string clientId, uint timeoutMilliseconds)
{
m_id = m_lastId++;
m_host = host;
m_port = port;
m_clientId = clientId;
m_timeoutMilliseconds = timeoutMilliseconds;
m_tcpClient = null;
m_cancelationSource = null;
}
~Client()
{
Disconnect();
}
/// <summary>
/// Attempts to connect to the hostname and port specified in the constructor
/// </summary>
/// <throws cref="System.ApplicationException" on failure
public void Connect()
{
Disconnect();
m_tcpClient = new TcpClient();
m_cancelationSource = new CancellationTokenSource();
try
{
m_tcpClient.Connect(m_host, (int)m_port);
}
catch (SocketException e)
{
string msg = string.Format("Client #{0} failed to connect to {1} on port {2}"
, m_id, m_host, m_port);
throw new System.ApplicationException(msg, e);
}
if (m_tcpClient.Connected)
{
log.Debug(string.Format("Client #{0} connnected to the Component on {1}"
, m_id, m_tcpClient.Client.RemoteEndPoint.ToString()));
}
}
public void Disconnect()
{
if (m_cancelationSource != null)
{
m_cancelationSource.Cancel();
// TODO - There needs to be some kind of wait here until the async methods all return!
// How to do that?
// Are we even supposed to be manually canceling? One would think TcpClient.Close takes care of that,
// however when deleting all cancelation stuff, instead we get exceptions from the async methods about
// using TcpClient's members after it was disposed.
m_cancelationSource.Dispose();
m_cancelationSource = null;
}
if (m_tcpClient != null)
{
m_tcpClient.Close();
m_tcpClient = null;
}
}
public void Login()
{
string loginRequest = string.Format("loginstuff{0}", m_clientId);
var data = Encoding.ASCII.GetBytes(loginRequest);
NetworkStream stream = m_tcpClient.GetStream();
Task writeTask = stream.WriteAsync(data, 0, data.Count());
// This will block until the login is sent
// We want block until the login is sent, so we can be sure we logged in before making requests
if( !writeTask.Wait((int)m_timeoutMilliseconds) )
{
// Error - Send timed out
log.Error(string.Format("Client #{0} Timed out while sending login request to the Component"
, m_id));
}
else
{
log.Debug(string.Format("Client #{0} sent login request to the Component"
, m_id));
}
}
public async void Read()
{
byte[] buffer = new byte[1024];
MemoryStream memoryStream = new MemoryStream();
NetworkStream networkStream = m_tcpClient.GetStream();
Task<int> readTask = null;
bool disconnected = false;
try
{
while (!disconnected)
{
readTask = networkStream.ReadAsync(buffer, 0, buffer.Length, m_cancelationSource.Token);
int bytesReceived = await readTask;
if (readTask.Status == TaskStatus.RanToCompletion)
{
if( bytesReceived <= 0)
{
disconnected = true;
continue;
}
memoryStream.Write(buffer, 0, bytesReceived);
// TODO - Handle parsing of messages in the memory stream
memoryStream.Seek(0, SeekOrigin.Begin);
}
else if (readTask.Status == TaskStatus.Canceled)
{
// Error - Read was cancelled
log.Error(string.Format("Client #{0} Read operation was canceled."
, m_id));
disconnected = true;
continue;
}
else
{
// Error - Unexpected status
log.Error(string.Format("Client #{0} Read operation has unexpected status after returning from await."
, m_id));
}
}
}
catch (System.Exception e)
{
log.Error(string.Format("Client #{0} Exception caught while reading from socket. Exception: {1}"
, m_id, e.ToString()));
}
}
public async void MakeRequest(string thingy)
{
string message = string.Format("requeststuff{0}", thingy);
var data = Encoding.ASCII.GetBytes(message);
NetworkStream networkStream = m_tcpClient.GetStream();
Task writeTask = null;
try
{
writeTask = networkStream.WriteAsync(data, 0, data.Count(), m_cancelationSource.Token);
await writeTask;
if (writeTask.Status == TaskStatus.RanToCompletion)
{
log.Debug(string.Format("Client #{0} sent request for thingy {1} to the Component"
, m_id, thingy));
}
else if (writeTask.Status == TaskStatus.Canceled)
{
// Error - Write was cancelled
log.Error(string.Format("Client #{0} Write operation was canceled while requesting thingy {1} from the Component"
, m_id, thingy));
}
else
{
// Error - Unexpected status
log.Error(string.Format("Client #{0} Write operation has unexpected status after returning from await, while requesting thingy {1} from the Component"
, m_id, thingy));
}
}
catch (System.Exception e)
{
log.Error(string.Format("Client #{0} Exception caught while requesting thingy {1}. Exception: {2}"
, m_id, thingy, e.ToString()));
}
}
}
}
main:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
using log4net.Config;
namespace IntegrationTests
{
class Program
{
private static readonly ILog log = LogManager.GetLogger("root");
static void Main(string[] args)
{
try
{
XmlConfigurator.Configure();
log.Info("Starting Component Integration Tests...");
Client client = new Client("127.0.0.1", 24001, "MyClientId", 60000);
client.Connect();
client.Read();
client.Login();
client.MakeRequest("Stuff");
System.Threading.Thread.Sleep(60000);
client.Disconnect();
}
catch (Exception e)
{
log.Error(string.Format("Caught an exception in main. Exception: {0}"
, e.ToString()));
}
}
}
}
I am running a program where a file gets uploaded to a folder in IIS,and then is processed to extract some values from it. I use a WCF service to perform the process, and BackgroundUploader to upload the file to IIS. However, after the upload process is complete, I get the error "The process cannot access the file x because it is being used by another process." Based on similar questions asked here, I gathered that the file concerned needs to be in a using statement. I tried to modify my code to the following, but it didn't work, and I am not sure if it is even right.
namespace App17
{
public sealed partial class MainPage : Page, IDisposable
{
private CancellationTokenSource cts;
public void Dispose()
{
if (cts != null)
{
cts.Dispose();
cts = null;
}
GC.SuppressFinalize(this);
}
public MainPage()
{
this.InitializeComponent();
cts = new CancellationTokenSource();
}
public async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
Uri uri = new Uri(serverAddressField.Text.Trim());
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
GlobalClass.filecontent = file.Name;
GlobalClass.filepath = file.Path;
BackgroundUploader uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", file.Name);
UploadOperation upload = uploader.CreateUpload(uri, file);
await HandleUploadAsync(upload, true);
stream.Dispose();
}
}
catch (Exception ex)
{
string message = ex.ToString();
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
}
private void CancelAll(object sender, RoutedEventArgs e)
{
Log("Canceling all active uploads");
cts.Cancel();
cts.Dispose();
cts = new CancellationTokenSource();
}
private async Task HandleUploadAsync(UploadOperation upload, bool start)
{
try
{
Progress<UploadOperation> progressCallback = new Progress<UploadOperation>(UploadProgress);
if (start)
{
await upload.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The upload was already running when the application started, re-attach the progress handler.
await upload.AttachAsync().AsTask(cts.Token, progressCallback);
}
ResponseInformation response = upload.GetResponseInformation();
Log(String.Format("Completed: {0}, Status Code: {1}", upload.Guid, response.StatusCode));
cts.Dispose();
}
catch (TaskCanceledException)
{
Log("Upload cancelled.");
}
catch (Exception ex)
{
string message = ex.ToString();
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
}
private void Log(string message)
{
outputField.Text += message + "\r\n";
}
private async void LogStatus(string message)
{
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
private void UploadProgress(UploadOperation upload)
{
BackgroundUploadProgress currentProgress = upload.Progress;
MarshalLog(String.Format(CultureInfo.CurrentCulture, "Progress: {0}, Status: {1}", upload.Guid,
currentProgress.Status));
double percentSent = 100;
if (currentProgress.TotalBytesToSend > 0)
{
percentSent = currentProgress.BytesSent * 100 / currentProgress.TotalBytesToSend;
}
MarshalLog(String.Format(CultureInfo.CurrentCulture,
" - Sent bytes: {0} of {1} ({2}%), Received bytes: {3} of {4}", currentProgress.BytesSent,
currentProgress.TotalBytesToSend, percentSent, currentProgress.BytesReceived, currentProgress.TotalBytesToReceive));
if (currentProgress.HasRestarted)
{
MarshalLog(" - Upload restarted");
}
if (currentProgress.HasResponseChanged)
{
MarshalLog(" - Response updated; Header count: " + upload.GetResponseInformation().Headers.Count);
}
}
private void MarshalLog(string value)
{
var ignore = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
Log(value);
});
}
}
}
After this is done, the file name is sent to a WCF service which will access and process the uploaded file to extract certain values. It is at this point I receive the error. I would truly appreciate some help.
public async void Extract_Button_Click(object sender, RoutedEventArgs e)
{
ServiceReference1.Service1Client MyService = new ServiceReference1.Service1Client();
string filename = GlobalClass.filecontent;
string filepath = #"C:\Users\R\Documents\Visual Studio 2015\Projects\WCF\WCF\Uploads\"+ filename;
bool x = await MyService.ReadECGAsync(filename, filepath);
}
EDIT: Code before I added the using block
try
{
Uri uri = new Uri(serverAddressField.Text.Trim());
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
GlobalClass.filecontent = file.Name;
GlobalClass.filepath = file.Path;
BackgroundUploader uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", file.Name);
UploadOperation upload = uploader.CreateUpload(uri, file);
await HandleUploadAsync(upload, true);
}
When you work with stream writers you actually create a process, which you can close it from task manager. And after stream.Dispose() put stream.Close().
This should solve your problem.
You should also close the stream that writes the file to disk (look at your implementation of CreateUpload).
i got such error in DotNet Core 2 using this code:
await file.CopyToAsync(new FileStream(fullFileName, FileMode.Create));
counter++;
and this is how I managed to get rid of message (The process cannot access the file x because it is being used by another process):
using (FileStream DestinationStream = new FileStream(fullFileName, FileMode.Create))
{
await file.CopyToAsync(DestinationStream);
counter++;
}
I am experiencing a memory leak in a c# console application and I am at a bit of a loss as to what is causing it.
I did a dump of the application at various stages to compare how the heap changed. I noticed there were many pinned object references and quite a few ActiveMq objects in there also. Below is my ActiveMq consumer, producer and connection. I am using the latest Apache.NMS.ActiveMQ nuget package.
public ActiveMqClient(ILogger logger, IAdaptorConfig config)
{
try
{
_config = config;
_logger = logger;
var connectionFactory = new ConnectionFactory(_config.ConnectionString);
_connection = connectionFactory.CreateConnection(_config.Username, _config.Password);
_connection.RequestTimeout = TimeSpan.FromSeconds(3);
_session = _connection.CreateSession();
_connection.Start();
_logger.Info(string.Format("Successfully created a connection to ActiveMq with client id:{0}, timeout {1} and prefetch policy {2}", _connection.ClientId, _connection.RequestTimeout, connectionFactory.PrefetchPolicy.QueuePrefetch));
}
catch (Exception e)
{
_logger.Error(string.Format("Failed to create connection to messaging service using connection string {0}, Exception: {1}", _config.ConnectionString), e.Message);
}
}
public void Subscribe()
{
try
{
var dest = _session.GetDestination(_config.InQueue);
_consumer = _session.CreateConsumer(dest);
_consumer.Listener += OnMessage;
_logger.Info(string.Format("Subscribed to activeMQ queue {0}", _config.InQueue));
}
catch (Exception ex)
{
_logger.Error(string.Format("Failed to subscribe to {1} . ex: {0}", ex.Message, _config.InQueue));
}
}
public void SendMessage(string message)
{
try
{
using (var dest = _session.GetDestination(_config.OutQueue))
using (var producer = _session.CreateProducer(dest))
{
producer.RequestTimeout = TimeSpan.FromSeconds(3);
var request = GetSession().CreateXmlMessage(message);
request.Text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + message;
producer.Send(request);
_logger.Info(string.Format("Created new producer and sending message to {0}", _config.OutQueue));
}
}
catch (Exception e)
{
_logger.Error("Problem sending message", e);
}
}
It is possible that the problem is coming from another part of the application entirely but it seems most likely to be activeMq at this point.
I wonder if anyone can spot anything that could cause the memory leak in my code? Let me know if I can give you any more information that could help!