lifestyle
lifestyle

Reputation: 198

How can implement awaiting manually?

As an example suppose we have this:

public class MyClass
{    
    public async Task<bool?> MySynchronousNonBlockingFunction()
    {
        await here ...

        return MyDialogResult;
    }      
}

and caller must call my function as below:

public async void Button_Click()
{
    var instance = new MyClass();

    var result = await instance.MySynchronousNonBlockingFunction(); 

    if (result == true)
    {
        some work ...
    }
}

But using Task for awaiting as a such, forces you to make your MySynchronousNonBlockingFunction() function async. And as a side effect you must call MyClass.MySynchronousNonBlockingFunction() only inside an async void to be worked as expected.

I think it is not well for the caller. Because a lazy developer in an application development team may call MySynchronousNonBlockingFunction() without await and then application will not works fine. I want handle this async operation in my code internally and not to the caller. To prevent this development mistakes. same as this one:

public void Button_Click()
{
    var instance = new MyClass();

    var result = instance.MySynchronousNonBlockingFunction();

    if (result == true)
    {
        some work ...
    }
}

In fact, i not want freeze the running thread by wait nor actually pause thread so it must be free to process other its works in another call stack again. Witch i want is actually same as the work of await keyword for a Task execution. is there another option to make this use? and what is your solution here to implement await behavior?

I know there is in c# some ways to lock an object full-fanced and force the execution stack to wait. (for example by using Monitor, or Mutex etc). And all the ways that i found in c# are blocking the running thread.

But, How can i implement awaiting manually? Is there another way to achieve this purpose?

Upvotes: 0

Views: 313

Answers (2)

Martin James
Martin James

Reputation: 24847

GUI window handlers are message-driven state-machines. You must write code that reflects that. That means no, you cannot sanely just wait, and you should not try.

Upvotes: 0

Stephen Cleary
Stephen Cleary

Reputation: 456332

In fact, i want pause ui thread from continue executing at a position, and then resume it again to continue execution in later (from CallStack snapshot position). But i not want freeze or actually pause therad so it must be free to process other its works in another call stack again. Witch i want is actually same as the work of await keyword for a Task execution. is there another option to make this use?

That's not how await works, though. await works by returning and then resuming just that method later. In particular, the call stack is not captured.

If you want to mess around with switching thread stacks, then check out fibers. However, there are no .NET bindings for the fiber APIs, and it's quite possible that a lot of .NET code will simply break if you try to use fibers instead of threads. Then there's the whole question of whether a fiber can actually be an STA context for UI elements; I'm really not sure about that one. In short, here be dragons.

and what is your solution here?

Well, a modal dialog - by definition - is supposed to block other dialogs and run a nested message loop.

If you don't want this behavior, then write modeless dialogs instead. I.e., call Show instead of ShowDialog.

Upvotes: 1

Related Questions