async callback that pops a message box? #1695
-
Im really stuck on this and I need to have user info on an async task (it calls a callback and is being awaited on the main thread through a lambda), in the callback i need to get input from a messagebox query and pass it back to the task (im doing this all async cause the task is updating a progressbar as well, which i have other issues with but thats not the main problem rn) but im getting the "Object is not set to instance of object" error when i call the messagebox or on Application.Run() when it gets to that point |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
You have to call inside of the lambda of |
Beta Was this translation helpful? Give feedback.
-
I needed a value out of it, i ended up using a ManualResetEvent to trigger when the value was gotten and resume but i feel like this is more of a bandaid than anything |
Beta Was this translation helpful? Give feedback.
-
This shows how to block an async task while you wait for the user to make a choice and then act upon that choice in the thread. In this case a progress bar loads and periodically asks the user how long to wait before loading the next chunk of the bar. Let me know if you have difficulty running this or don't understand or if it isn't relevant to your question. using System.Collections.ObjectModel;
using Terminal.Gui;
namespace Tests
{
class Program
{
static ProgressBar pb;
static void Main(string[] args)
{
Application.Init();
var win = new Window()
{
X = 0,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill()
};
pb = new ProgressBar()
{
X = 0,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill(),
};
win.Add(pb);
object oLock = new object();
Task.Run(()=>
{
int? waitTime = 100;
for(int i=0;i<10;i++)
{
// wait for user to interact with dialog and pick a duration
// Note that this only happens on the second iteration
while(waitTime == null)
{
Task.Delay(10).Wait();
}
// wait for howeverlong the user asked (or 100 first time)
lock(oLock)
{
Task.Delay(waitTime.Value).Wait();
}
// clear how long we are waiting for
// it is important to do this before launching dialog
// so that in this thread we can block and wait for user input (see above)
waitTime = null;
// update the progress bar
Application.MainLoop.Invoke(()=>{
pb.Fraction = i/(float)10;
pb.SetNeedsDisplay();
});
// Ask user how long they want to wait for. Note that this Invoke method
// is non blocking i.e. it says 'run the message box when you next get a chance'
Application.MainLoop.Invoke(()=>{
lock(oLock)
{
var wait = MessageBox.Query("Wait for?","How long to wait?","100ms", "5000ms");
// when user closes form we save the value which unlocks the main Task iteration to continue
waitTime = wait == 0 ? 100 : 5000;
}
});
}
});
Application.Top.Add(win);
Application.Run();
Application.Shutdown();
}
}
} |
Beta Was this translation helpful? Give feedback.
This shows how to block an async task while you wait for the user to make a choice and then act upon that choice in the thread. In this case a progress bar loads and periodically asks the user how long to wait before loading the next chunk of the bar.
Let me know if you have difficulty running this or don't understand or if it isn't relevant to your question.