As below code runs async, 2 zip created with same name and when trying to copy destination, getting error saying that,
The file 'C:\Temp\test_20181024032123496.Zip' already exists.
How to skip this condition? Thanks!
private static async Task<bool> GenerateZipFile(FileSystemInfo file1, string zipFilePath)
{
try
{
using (var zip = ZipFile.Open($"{zipFilePath}\\test_{DateTime.UtcNow:yyyyMMddHHmmssfff}.Zip", ZipArchiveMode.Create))
{
zip.CreateEntryFromFile(file1.FullName, file1.Name, CompressionLevel.Optimal);
}
}
catch (Exception ex)
{
Console.Write(ex);
}
}
Ok, so I'm not sure if you have the problem with the zip file you're creating or with the file you're adding into the zip file so I'm adding code that checks if either of them exists
private static async Task<bool> GenerateZipFile(FileSystemInfo file1, string zipFilePath)
{
try
{
string newZipFilePath = $"{zipFilePath}\\test_{DateTime.UtcNow:yyyyMMddHHmmssfff}.Zip"
if (!System.IO.File.Exists(newZipFilePath))
{
using (var zip = ZipFile.Open(newZipFilePath, ZipArchiveMode.Create))
{
if(System.IO.File.Exists(file1.FullName))
{
zip.CreateEntryFromFile(file1.FullName, file1.Name, CompressionLevel.Optimal);
}
}
}
}
catch (Exception ex)
{
Console.Write(ex);
}
}
This should work, but you should also check which is the one you actually need and only use that one
Related
I created an app that needs to store user data in a file that is created on Application start and when I compile it, it shows me this System.IO.FileLoadException: Could not find or load a specific file. (Exception from HRESULT: 0x80131621) and this System.NullReferenceException: Invalid pointer.
When the Application starts it calls the Init() Method before everything.
public static class FilesManager
{
public static StorageFolder ROOT_DIRECTORY, USER_DIRECTORY;
public static StorageFile FILES_MANAGER_CACHE_FILE;
public static volatile string FILES_MANAGER_CACHE;
public static volatile StorageFolder FOLDER;
public static async Task Init()
{
try
{
FOLDER = await ApplicationData.Current.LocalFolder.CreateFolderAsync("DashData", CreationCollisionOption.OpenIfExists);
FOLDER = await ApplicationData.Current.LocalFolder.GetFolderAsync("DashData");
if (FOLDER == null) Debug.WriteLine("FOLDER IS NULL.");
FILES_MANAGER_CACHE_FILE = await FOLDER.CreateFileAsync("filesmanageruserdata.json", CreationCollisionOption.OpenIfExists);
FILES_MANAGER_CACHE_FILE = await FOLDER.GetFileAsync("filesmanageruserdata.json");
await LoadFilesManagerCacheAsync();
Debug.WriteLine("TEXT: " + FILES_MANAGER_CACHE);
}
catch(Exception e)
{
Debug.WriteLine("ERROR: " + e.ToString());
}
}
public static async Task LoadFilesManagerCacheAsync()
{
FILES_MANAGER_CACHE = await FileIO.ReadTextAsync(FILES_MANAGER_CACHE_FILE);
}
public static async Task storeUserData(string content)
{
try
{
await FileIO.WriteTextAsync(FILES_MANAGER_CACHE_FILE, content);
}catch(Exception e)
{
Debug.WriteLine("ERROR: " + e.ToString());
}
}
}
I learning Xamarin, I use a function to delete all my sqlite database, add new elements and refesh my listview.
the code stop, I thinks it is because it has not time for delete first,add in database then refresh thelist view. When I add a timer (2 seconds) it works.
Here is the error at the line "mywordsdatabase.DeleteAllWords();" : System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index'
I am using this sqlite plugin enter link description here
Here is the function :
public async void DeleteAndUpdate(){
mywordsdatabase.DeleteAllWords(); // the error occur here
List<MyWords> WordUserList = await wordmanager.GetWordAsync(UserConnected.MyId);
foreach (MyWords w in WordUserList)
{
mywordsdatabase.AddWord(w);
}
var WordList = await mywordsdatabase.GetWords();
Device.BeginInvokeOnMainThread(() => { WordSList.ItemsSource = WordList; });
}
Here is the Delete function for sqlite:
class MyWordsDatabase
{
private SQLiteAsyncConnection conn;
//CREATE
public MyWordsDatabase()
{
conn = DependencyService.Get<ISQLite>().GetConnection();
conn.CreateTableAsync<MyWords>();
}
public string AddWord(MyWords mywords)
{
conn.InsertAsync(mywords);
return "success";
}
public string DeleteAllWords()
{
conn.DeleteAllAsync<MyWords>();
return "success";
}
}
Thanks for your help
Few things to check, first of ensure the database actually has words to delete, as the error would suggest that it tried to operate upon a null element. Secondly, since the method is async, see if changing the signature will help.
So instead of public string DeleteAllWords() it becomes public async string DeleteAllWords() then inside of the method we can say await conn.DeleteAllAsync<MyWords>(); and where we call it we can then do await mywordsdatabase.DeleteAllWords();
As jmcil said, async code won't wait for its operation to stop execution unless told to do so.
The whole point of asynchronous methods is that they are asynchronous, i.e. they return immediately while the work they initiated continues in the background. If you call that DeleteAllAsync method and then immediately start executing code as though it has finished deleting everything then of course you'll have issues. If you need the deletion to be completed before subsequent code is executed then you need to wait until the deletion is completed before executing that subsequent code. The way to do that is most likely to await the awaitable methods in your code. This:
public string DeleteAllWords()
{
conn.DeleteAllAsync<MyWords>();
return "success";
}
probably ought to be this:
public async Task<string> DeleteAllWordsAsync()
{
await conn.DeleteAllAsync<MyWords>();
return "success";
}
That means that you can either await the call to that method:
await mywordsdatabase.DeleteAllWordsAsync();
or you can trap the Task it returns, execute some code that doesn't depend on it completing and then await the Task later:
var t = mywordsdatabase.DeleteAllWordsAsync();
// ...
await t;
Please change your DeleteAllWords method like following method.
public Task<int> DeleteAllNotesAsync()
{
return conn.DeleteAllAsync<MyWords>();
}
Then judge the return value if it greater than 0, it the return value greater than 0, it means delete success like this simple code.
private async void Button_Clicked(object sender, EventArgs e)
{
int deleteRecord= await App.Database.DeleteAllNotesAsync();
if (deleteRecord>0)
{
await DisplayAlert("Success", "delete" + deleteRecord, "OK");
}
}
public async Task<string> AddWord(MyWords mywords)
{
string result=string.Empty;
try
{
await conn.InsertAsync(mywords);
}
catch (Exception ex)
{
}
return result;
}
public async Task<string> DeleteAllWords()
{
string result = string.Empty;
try
{
await conn.DeleteAllAsync<MyWords>();
}
catch (Exception ex)
{
}
return result;
}
public async void DeleteAndUpdate()
{
try
{
await mywordsdatabase.DeleteAllWords(); // the error occur here
List<MyWords> WordUserList = await wordmanager.GetWordAsync(UserConnected.MyId);
foreach (MyWords w in WordUserList)
{
await mywordsdatabase.AddWord(w);
}
var WordList = await mywordsdatabase.GetWords();
Device.BeginInvokeOnMainThread(() => { WordSList.ItemsSource = WordList; });
}
catch (Exception ex)
{
}
}
I am trapped with definitions of Entity framework and using objects.
I am trying to save an uploaded file once I am saving the details related to that file in my database.
public async Task<IActionResult> Edit(string List<IFormFile> files, [Bind("param")] Entity entity)
{
if (ModelState.IsValid)
{
try
{
_context.Update(entity);
await _context.SaveChangesAsync();
//update Attachments
if (files.Count > 0)
{
attachment.UploadFiles(files);
}
}
catch (DbUpdateConcurrencyException)
{
if (!EntityExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(entity);
}
When I run the application and want to submit the form I receive below error:
Cannot access a disposed object.
Object name: 'FileBufferingReadStream'.
[HttpPost]
public async void UploadFiles(List<IFormFile> files)
{
if (files == null || files.Count == 0)
{
log.error("files not selected");
}
try
{
List<string> filenames = new List<string>();
string directory = Directory.GetCurrentDirectory() + "\\wwwroot";
createDir(directory);
foreach (var file in files)
{
string filename = file.GetFilename();
filenames.Add(filename);
}
if (filenames.Count > 0)
foreach (var filename in filenames)
{
AttachmentQ(filename, directory, createdBy);
}
foreach (var file in files)
{
string filename = file.GetFilename();
var path = Path.Combine(directory, filename);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
filenames.Add(filename);
}
}
catch (Exception e)
{
log.error(e.Message);
}
}
[ValidateAntiForgeryToken]
public async void AttachmentQ(string filename, string path, string createdBy)
{
try
{
Attachment attachment = new Attachment
{
Name = filename,
Path = path,
CreatedBy = createdBy,
CreatedDate = DateTime.Now
};
_context.Add(attachment);
await _context.SaveChangesAsync();
}
catch (Exception e)
{
log.error(e.Message);
}
}
Surprisingly I don't get error in debug mode. But when I run the app I get This page isn’t working error.
I also noticed I need to return a value when I use async but I don't have any return vale in UploadFiles() and AttachmentQ() methods.
Could you please help me how to handle objects when using different contexts. Thanks
Do NOT use async void at all.
if you want to use async/await pattern then let your methods returns Task
public async Task UploadFiles(List<IFormFile> files)
When I delete file like this behind, it throws an exception:
Value does not fall within the expected range.
when deleteasync.
public static async Task DeleteFile(string fileName, string folderPath)
{
try
{
StorageFolder sf = await CheckFolder(folderPath);
StorageFile sfile = await sf.GetFileAsync(fileName);
if (sfile != null)
{
await sfile.DeleteAsync();
}
}
catch (Exception)
{
}
}
I am changing a method that used to accept string for temp folder and string for file and changing it to a stream and i wanted some help how to check if file exists or not.
bool UploadFile(Stream inputStream, Stream inputFile);
This is what i originally had and i want to change so the parameters accepts a stream
bool UploadFile(string tempFolder, string fileName)
public bool UploadFile(string tempFolder, string fileName)
{
if (File.Exists(fileName))
{
testingUsage.Upload(tempFolder, fileName);
return testingUsage.Exists(tempFolder);
}
return false;
}
do i create two streams one for the file and one for location?
Assuming this is your Upload Action:
[HttpPost]
public ActionResult Upload()
{
try
{
if (Request.Files.Count > 0)
{
string tempFolder = "...";
var file = Request.Files[0];
if(UploadFile(tempFolder, file))
{
// Return a View to show a message that file was successfully uploaded...
return View();
}
}
}
catch (Exception e)
{
// Handle the exception here...
}
}
Your Method can be something like this:
private bool UploadFile(string tempFolder, HttpPostedFileBase file)
{
var path = Path.Combine(tempFolder, file.FileName);
// if the file does not exist, save it.
if (!File.Exists(path))
{
file.SaveAs(path);
return true;
}
return false;
}