|
Message Closed
modified 26-Jan-17 4:35am.
|
|
|
|
|
What have you tried?
What does the debugger show?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
|
I don't understand exactly what the method "GetData" is doing ... but the method "existingFile" exactly work like you described :
it opens the Workbook, do something in GetData and finally save the changed Workbook (by overwriting the old version of the Workbook before).
So ... where is your Problem ?
|
|
|
|
|
It's really quite simple. If the file exists, then you need first to read the data from the Worksheet into the DataGridView. You can then allow the user to add or modify the data on display before saving it back to the file.
|
|
|
|
|
int lastRow_ = 3;
I fear you forgot to skip existing data before writing new data.
You need to detect existing data and write new data after existing data. you probably also want to not write headers again.
When you don't understand what your code is doing or why it does what it does, the answer is debugger.
Use the debugger to see what your code is doing. It allow you to execute lines 1 by 1 and to inspect variables as it execute, it is an incredible learning tool.
Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't find bugs, it just help you to. When the code don't do what is expected, you are close to a bug.
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
I have a form Form1 on which is a listbox and a button.
Consider the following code, and read the problem I am having with it below:
private async void button1_Click(object sender, EventArgs e)
{
listBox.Items.AddRange(new object[] {"Hello", "There", "Code", "Project."});
await PerformLengthyTask();
}
private async Task<bool> PerformLengthyTask()
{
Thread.Sleep(5000);
return true;
}
What I THOUGHT would happen when I clicked the button:
The new items would appear instantly in the listbox because while the UI thread is waiting for the PerformLengthyTask function, it is free to pump messages and keep the UI responsive.
What ACTUALLY happens when I click the button:
The new items do not appear in the listbox until after PerformLengthyTask returns.
And also, the form itself is frozen.
What is it that I do not understand about async methods that is causing me this confusion?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Well, it looks like you're firing of the thread.sleep on the UI (calling) thread so...that's expected.
A better test case might look like:
private async void button1_Click(object sender, EventArgs e)
{
listBox.Items.AddRange(new object[] {"Hello", "There", "Code", "Project."});
var task = Task.Run(() => PerformLengthyTask()).ContinueWith(s => DoSomethingWithBool(s));
}
private async Task<bool> PerformLengthyTask()
{
Thread.Sleep(5000);
return true;
}
This will push the method onto a different thread, will not block, and will take a callback.
Really async and await are ways to transition from an asynchronus context into a synchronous one. The await keyword ostensibly forces code execution into a synchronous context by marking a place where a Task.Result needs to be available.
Async and await make life much, much easier in terms of interacting with async code, but they are not a silver bullet on their own.
For detailed reading have a look at:
Task-based Asynchronous Pattern (TAP)
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Thank you for your post. I did indeed believe it was a silver bullet for making function calls asynchronous. I thought that the await keyword was all that was required to push a task onto a different thread.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
The async keyword doesn't make a function asynchronous. It gives you access to the await keyword. Await can be used on any call that returns a Task<T> or Task . Await checks whether the Task.IsCompleted is true then if not it captures the current context and sets the remaining code in the function as a continuation after the awaited task completes. Then the function returns control to its caller.
Since PerformLengthyTask is a function call executed in the UI context, when you sleep on the current thread it is sleeping the UI thread. async /await are used to easily allow asynchronous behavior when calling code which waits on something to complete execution. That something could be on a thread pool thread, an external server, another thread, or whatever. Also a method doesn't have to be async to return Task or Task<T> but an async method has to return either one of those or void .
This example will add the items to the listbox, return control back to the UI, and when the delay expires so the result gets set PerformLengthyTask will continue with return true which will set its result so button1_Click can continue with whatever it wants to do with the boolean.
private async void button1_Click(object sender, EventArgs e)
{
Task<bool> lengthyTask = PerformLengthyTask();
listBox.Items.AddRange(new object[] {"Hello", "There", "Code", "Project."});
bool result = await lengthyTask;
}
private async Task<bool> PerformLengthyTask()
{
await Task.Delay(5000);
return true;
}
private async Task<bool> PerformLengthyTask()
{
await DelayAsync(5000);
return true;
}
private Task DelayAsync(int delay)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
ThreadPool.QueueUserWorkItem(_ =>
{
Thread.Sleep(delay);
tcs.SetResult(false);
});
return tcs.Task;
}
TaskCompletionSource<T> has no non-generic so a dummy TResult of bool is used in DelayAsync . Note that if you don't need to synchronize back to the captured context you can use await DelayAsync(5000).ConfigureAwait(false) . This is useful if you don't need to update any UI objects for example.
Your listbox might not be updating because your listbox view isn't refreshed
Bonus Edit: This doesn't use async /await but accomplishes the same thing.
private void button1_Click(object sender, EventArgs e)
{
PerformLengthyTask().ContinueWith(task =>
{
bool result = task.Result;
}, TaskScheduler.FromCurrentSynchronizationContext());
listBox.Items.AddRange(new object[] {"Hello", "There", "Code", "Project."});
}
private Task<bool> PerformLengthyTask()
{
DelayAsync(5000).ContinueWith(_ => true);
}
private Task DelayAsync(int delay)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
ThreadPool.QueueUserWorkItem(_ =>
{
Thread.Sleep(delay);
tcs.SetResult(false);
});
return tcs.Task;
}
modified 25-Jan-17 1:39am.
|
|
|
|
|
Thank you for your detailed explanation. I feel better prepared to tackle this subject further.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
No need for your DelayAsync method - just call Task.Delay[^] instead.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Well aware The comment above that says "//or not using Task.Delay" and immediately above that is an example using Task.Delay . I was simply showing how you could manually do that operation to provide another viewpoint
|
|
|
|
|
It's worth pointing out that Task.Delay uses a Timer behind the scenes to trigger the completion. That's more efficient than your DelayAsync method, because it doesn't keep a thread-pool thread hanging around waiting for a Thread.Sleep call to complete.
The Task.Delay source code[^] uses some internal stuff, so if the method didn't exist, you'd want something like this:
private sealed class DelayPromise
{
private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
private readonly Timer _timer;
public DelayPromise(int millisecondsDelay)
{
_timer = new Timer(state => ((DelayPromise)state).Complete(), this, millisecondsDelay, Timeout.Infinite);
}
public Task Task
{
get { return _taskCompletionSource.Task; }
}
private void Complete()
{
if (_taskCompletionSource.TrySetResult(true))
{
_timer.Dispose();
}
}
}
public static Task DelayAsync(int millisecondsDelay)
{
var promise = new DelayPromise(millisecondsDelay);
return promise.Task;
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Neat, I didn't know Task.Delay used a Timer . Learn something new every day! Yea, that would be more efficient since Timer uses the native API to determine when to schedule the callback so doesn't sleep a thread but I just wanted a simple example
modified 25-Jan-17 17:02pm.
|
|
|
|
|
|
Looks like you've already got some good explanations as to why Thread.Sleep doesn't work, but nobody's mentioned the obvious replacement: Task.Delay[^]:
private async void button1_Click(object sender, EventArgs e)
{
listBox.Items.AddRange(new object[] {"Hello", "There", "Code", "Project."});
await PerformLengthyTask();
}
private async Task<bool> PerformLengthyTask()
{
await Task.Delay(5000);
return true;
}
Thread.Sleep will block the current thread (which is the UI thread) for 5 seconds.
Task.Delay will return a Task which will be completed in 5 seconds. Awaiting that task will sign up the rest of the method as a continuation, without blocking the thread.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Deeming wrote: Task.Delay will return a Task which will be completed in 5 seconds.
Hmm. Very interesting. <strokes chin>
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
How can implement delegate in project structure,what main purpose to use delegates in C#
|
|
|
|
|
|
Delegates are basically just function pointers (albeit function pointers on steroids) - and in C# you use them all the time, but behind the scenes. All Events in C# are handled via Delegates and would not work without them.
But ... it's a big subject, so have a look at this: C# Delegates: Step by Step[^] and perhaps this as well: Events and Delegates Simplified[^]
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
How Can Export The Sql-server Data With The SSIS from In any Excell and How Can Code In the c# To Take any Particular Directory
|
|
|
|
|
The simple answer is to use Google to do some research. When you have a specific question then come back here and people will try to help you.
|
|
|
|
|
Why is my code not returning numbers such as 20000, 30000, 40000 etc. it just returns twenty and ignores the thousand.
Console.WriteLine(DateTime.Now);
Console.WriteLine("Welcome To Ayoola's Number Converter");
string[] units = new string[] { " ","ONE ", "TWO ", "THREE ", "FOUR ", "FIVE ", "SIX ", "SEVEN ", "EIGHT ", "NINE ", "TEN ", "ELEVEN ", "TWELVE ", "THIRTEEN ", "FOURTEEN ", "FIFTEEN ", "SIXTEEN ", "SEVENTEEN ", "EIGHTEEN ", "NINETEEN " };
string[] tens = new string[] { " ","TEN ", "TWENTY ", "THIRTY ", "FOURTY ", "FIFTY ", "SIXTY ", "SEVENTY ", "EIGHTY ", "NINETY " };
string[] big = new string[] { "hundred ", "Thousand ", "million", "billion" };
long i, num;
string result = "";
Console.WriteLine("Enter number here : ");
String input = Console.ReadLine();
num = long.Parse(input);
if (num < 1000000000000 && num > 99999999999)
{
i = num / 100000000000;
result = units[i] + "HUNDRED " + "AND ";
num = num % 100000000000;
}
if (num > 19999999999 && num < 100000000000)
{
i = num / 10000000000;
result += tens[i];
num = num % 10000000000;
}
if (num > 999999999 && num < 20000000000)
{
i = num / 1000000000;
result += units[i] + "BILLION ";
num = num % 1000000000;
}
if (num > 99999999 && num < 1000000000)
{
i = num / 100000000;
result += units[i] + "HUNDRED " + "AND ";
num = num % 100000000;
}
if (num >= 20000000 && num < 100000000)
{
i = num / 10000000;
result += tens[i] ;
num = num % 10000000;}
if (num >= 1000000 && num < 20000000)
{
i = num / 1000000;
result += units[i] + "MILLION ";
num = num % 1000000;
}
if (num > 100000 && num < 1000000)
{
i = num / 100000;
result += units[i] + "HUNDRED " + "AND " ;
num = num % 100000;
}
if (num > 19999 && num < 100000)
{
i = num / 10000;
result += tens[i];
num = num % 10000;
}
if (num > 999 && num <= 19999)
{
i = num / 1000;
result += units[i] + "THOUSAND ";
num = num % 1000;
}
if (num > 99 && num < 1000)
{
i = num / 100;
result += units[i] + "HUNDRED " + "AND ";
num = num % 100;
}
if (num > 19 && num < 100)
{
i = num / 10;
result = result + tens[i];
num = num % 10;
}
if (num < 20 && num >= 0)
{ result += units[num]; }
if (num == 0)
result += "";
Console.WriteLine("The number in words: " + result);
string sample = "1234";
string s = "1234";
for (int y = s.Length ; y > 0; y-= 3 )
{
if(y-3 > 0)
{
Console.WriteLine(s.Substring(y - 3, 3));
}
}
Console.WriteLine(sample.Substring(1,3));
Console.ReadLine();
|
|
|
|
|
Look at the following code:
if (num > 19999 && num < 100000)
{
i = num / 10000;
result += tens[i];
num = num % 10000;
}
If you start with 20,000, then i will become 2, and num will become zero. But in the code that follows you have no way of determining that the 2 refers to thousands. You need to rethink your calculations.
|
|
|
|
|