暂停方法直到单击按钮

时间:2017-07-15 16:45:30

标签: c# .net asynchronous

如何暂停方法执行或当前迭代,直到用户按下一个按钮为止?

我想要一种有效的方法,因为我无法将方法划分为其他方法,我不想使用 public void Calc(int x) { while(x < 4) { //My Work textbox1.Text += "Press next to continue"; //Need to pause the iteration until taking a signal from a button } } void button1(...) { Calc(1); } ,因为它会冻结GUI。

{{1}}

2 个答案:

答案 0 :(得分:0)

使用SemaphoreSlim

由于async / await调度,您可以在UI线程上运行工作和按钮代码。并且您可以重复使用相同的信号量实例来生成多个信号。

//not signaled semaphore with maximum of 1 signal
SemaphoreSlim _workSignal = new SemaphoreSlim(0,1);

您的工作代码:

async void DoWork()
{
    //Do Something
    //this tries to decrease signal count and if signal count is 0, 
    //waits until it will have some signals, then "takes" 
    //one signal to go through. 
    //After this line the semaphore will be in non-signaled state
    await _workSignal.WaitAsync(); 
    //Do more
}

您的按钮处理程序

void Button_Click(...) 
{ 
    _signal.Release();//increases signal count, allowing your work code to go through
}

答案 1 :(得分:0)

我认为简单的ManualResetEvent以及异步方法可以帮助您:

public partial class Form1 : Form
{
    private ManualResetEvent _calcEvent;

    private delegate void ChangeTextMethod(string text);

    private ChangeTextMethod _changeTextHandler;


    public Form1()
    {
        InitializeComponent();
        _calcEvent = new ManualResetEvent(false);
        _changeTextHandler = delegate (string text) {
            textbox1.Text += text;
        };
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Calc(1);
    }

    public async Task Calc(int x)
    {
        await Task.Run(() => {
            while (x < 4)
            {
                //My Work
                textbox1.Invoke(_changeTextHandler, "Press next to continue");
                //Need to pause the iteration until taking a signal from a button
                _calcEvent.WaitOne();
                x = 4;
            }
            textbox1.Invoke(_changeTextHandler, "... continued");
        });
    }

    private void button2_Click(object sender, EventArgs e)
    {
        _calcEvent.Set();
    }
}