Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 所有工作同步时显示等待光标_C#_Winforms_Async Await - Fatal编程技术网

C# 所有工作同步时显示等待光标

C# 所有工作同步时显示等待光标,c#,winforms,async-await,C#,Winforms,Async Await,在我的Winforms应用程序中,启动操作时,可以异步执行,也可以不异步执行。在所有工作都是同步完成的情况下,我无法使用异步完成工作时使用的相同方法显示等待光标 下面是一个显示问题的示例: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs

在我的Winforms应用程序中,启动操作时,可以异步执行,也可以不异步执行。在所有工作都是同步完成的情况下,我无法使用异步完成工作时使用的相同方法显示等待光标

下面是一个显示问题的示例:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var t = ButtonClick(button1, DoWorkAsync1);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        var t = ButtonClick(button2, DoWorkAsync2);
    }

    private async Task ButtonClick(Button btn, Func<Task> doWorkAsync)
    {
        // Disable the UI and show the wait cursor
        btn.Text = "Working...";
        btn.Enabled = false;
        UseWaitCursor = true;

        // Application.DoEvents(); // Inserting this causes the problem to go away.
        await doWorkAsync();

        // Simulate an update of the UI taking a long time
        Thread.Sleep(2000); 

        // Renable the UI and stop showing the wait cursor
        UseWaitCursor = false;
        btn.Enabled = true;
    }

    private Task DoWorkAsync1()
    {
        // Work takes some time
        return Task.Delay(2000); 
    }

    private Task DoWorkAsync2()
    {
        // Work doesn't take any time, results are immediately available
        return Task.FromResult<int>(0); 
    }
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
变量t=按钮单击(按钮1,DOWORKSync1);
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
变量t=按钮单击(按钮2,DOWORKSync2);
}
专用异步任务按钮单击(按钮btn,Func doWorkAsync)
{
//禁用UI并显示等待光标
btn.Text=“工作…”;
btn.Enabled=false;
UseWaitCursor=true;
//Application.DoEvents();//插入此选项会导致问题消失。
等待doWorkAsync();
//模拟花很长时间更新UI
《睡眠》(2000年);
//重新启动UI并停止显示等待光标
UseWaitCursor=false;
btn.Enabled=true;
}
专用任务DoWorkAsync1()
{
//工作需要一些时间
返回任务。延迟(2000);
}
专用任务DoWorkAsync2()
{
//工作不需要任何时间,结果立即可用
返回Task.FromResult(0);
}
}
在本例中:

  • 单击按钮1会显示等待光标(因为工作是异步完成的)
  • 单击按钮2不会显示等待光标(因为所有工作都是同步完成的)
  • 单击按钮1和按钮2都会按预期禁用UI
所需的是,单击按钮1或按钮2应导致在单击按钮和完成UI更新工作之间的整个时间间隔内显示等待光标

问题:

  • 有没有办法解决这个问题而不插入
    应用程序.DoEvent
    (或任何会导致消息泵送发生的等效程序),或者只能通过泵送消息来实现
  • 旁白:为什么控件的禁用工作正常(与光标不同)

如果要在后台线程上执行同步工作,请在
任务中调用它。运行
然后等待
结果(调用代码将其视为异步)

或者,如果您的同步工作确实是即时的,并且您确实希望在其他UI工作之前应用一些UI更新(例如,游标),那么您只需执行以下操作:

await Task.Delay(10);

而不是
DoEvents
插入:

await Task.Run(() => { });
这将确保等待的任务在启动时没有正确完成,因此该方法的其余部分将作为延续而不是同步运行

或者,您可以直接向
doworksync
添加一个continuation,以确保它不会同步运行:

await doWorkAsync
    .ContinueWith(t => { }, TaskContinuationOptions.HideScheduler);

我没有我想在后台线程上做的同步工作。如果你真的有2秒的UI工作要做,那么这就是所需要的时间。没有魔法。我不想要任何魔法——我想在这两秒钟内显示等待光标。关键是2秒钟的UI更新表明存在严重的设计问题。也许您应该使用虚拟化控件?等待光标不用于显示UI更新;也就是说,我已经用一个黑客更新了我的答案,应该可以做你想要的。可能是@HansPassant的重复,谢谢——答案是:UseWaitCursor正在等待WM_SETCURSOR消息。此解决方案适合我。@MattSmith SetCursor将帮助您显示任何类型的自定义游标或标准游标,
等待游标
只是一件非常简单的事情。为什么不
等待任务。Yield()
?@svick我运行了一些测试,但它不起作用。这是我第一次想到什么应该有效。嗯,空线程池任务可以很容易地以非确定性的方式内联。为什么屈服不起作用?好奇。@usr AFAIK
wait
从不内联
Task
s。当然不是UI线程。虽然
任务
在等待
ed之前完成的可能性很小。
await doWorkAsync
    .ContinueWith(t => { }, TaskContinuationOptions.HideScheduler);