Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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 - Fatal编程技术网

C# 无需等待的响应形式

C# 无需等待的响应形式,c#,winforms,C#,Winforms,假设你在表单中做了很多事情 while(true) { DoStuff(); } 这会导致问题:当循环执行时,表单停止重画并锁定 goto解决方案是使用async/await while(true) { await Task.Run(DoStuff); } …或是一些变化 但是,如果周期很短,这将导致出现新的任务对象,并且GC难以分解它们。虽然现代机器可以毫无问题地处理这个问题,但我认为还是应该避免这种情况 我发现您可以使用Control.Invalidate()解决重画问题

假设你在表单中做了很多事情

while(true)
{
    DoStuff();
}
这会导致问题:当循环执行时,表单停止重画并锁定

goto解决方案是使用async/await

while(true)
{
    await Task.Run(DoStuff);
}
…或是一些变化

但是,如果周期很短,这将导致出现新的任务对象,并且GC难以分解它们。虽然现代机器可以毫无问题地处理这个问题,但我认为还是应该避免这种情况

我发现您可以使用
Control.Invalidate()
解决重画问题。只要保持焦点,它就会重新绘制表单

while(true)
{
    DoStuff();
    MyControl.Invalidate();
    //or
    MyForm.Refresh();
}
然而,我不知道如何避免锁定

据我所知,表单在一个线程上运行,因此当我的代码执行时,表单无法处理windows消息。在cpp程序中,您只需自己在每个周期中遍历消息缓冲区。但是你能在这里做什么呢

但是,如果周期很短,这将导致出现新的任务对象,并且GC难以分解它们。虽然现代机器可以毫无问题地处理这个问题,但我认为还是应该避免这种情况

请允许我引用Donald Knuth的话:

程序员浪费大量时间考虑或担心其程序中非关键部分的速度,而在考虑调试和维护时,这些提高效率的尝试实际上会产生强烈的负面影响。我们应该忘记小效率,比如说97%的时间:过早优化是万恶之源


换句话说,使用
等待任务。运行
如果且仅当性能分析表明存在性能问题,则探索替代解决方案。如果性能分析确实表明存在问题,我建议的第一个替代解决方案是增加
任务中的代码量。运行

如果你想老一套,使用手动线程,你的代码看起来会与你原来的想法相似。我在关键领域发表了一些评论,以提醒您注意注意注意事项。BackgroundWorker控件为您处理此类内容:

private System.Threading.Thread T;

private void Form1_Shown(object sender, EventArgs e)
{
    T = new System.Threading.Thread(new System.Threading.ThreadStart(backgroundThread));
    T.IsBackground = true; // optional: allows program to close even when T is running
    T.Start();
}

private void backgroundThread()
{
    while (true)
    {
        DoStuff();

        this.Invoke((MethodInvoker)delegate() {
            // It's safe to update the UI from within this block
            //
            // This should be done sparingly or it negates the
            // whole process of using a separate thread!
        });

        System.Threading.Thread.Sleep(100); // slight CPU break
    }
}

private void DoStuff()
{
    // foo();
    // bar();
    // stuff();
}
我想要的是:

while(true)
{
DoStuff();
MyForm.Invalidate();
Application.DoEvents();
}

虽然可以说更好的解决方案是不使用C#来解决我的问题…

您应该遵循异步/等待路径。您不能将while循环放在
任务中吗?
?是的,在winforms中它是
控件。Invoke()
@Ackdari Yes,但是如果您使用async/Wait足够明智,那么所有这些都将在scenes@Ackdari您可以使用Task.Run让cpu绑定的代码在后台运行而不阻塞并等待该任务。阅读