Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.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# 是否需要调用才能从异步方法访问DataGridView.SelectedRows?_C#_Winforms_Datagridview_Async Await_Invoke - Fatal编程技术网

C# 是否需要调用才能从异步方法访问DataGridView.SelectedRows?

C# 是否需要调用才能从异步方法访问DataGridView.SelectedRows?,c#,winforms,datagridview,async-await,invoke,C#,Winforms,Datagridview,Async Await,Invoke,我有这样一种方法: async Task foo() { foreach (DataGridViewRow row in dataGridView1.SelectedRows) { // ... } } await Task.Run(() => { foo(); }); 这样称呼: async Task

我有这样一种方法:

 async Task foo() {
         foreach (DataGridViewRow row in dataGridView1.SelectedRows) {
         // ...
        }
}
await Task.Run(() =>
                    {
                        foo();
                    });
这样称呼:

 async Task foo() {
         foreach (DataGridViewRow row in dataGridView1.SelectedRows) {
         // ...
        }
}
await Task.Run(() =>
                    {
                        foo();
                    });

我刚刚注意到代码正在访问
dataGridView1。SelectedRows
直接访问,无需调用,工作正常。我正在执行无效的操作吗?这应该有效还是必须在这里使用invoke?

这是因为您使用
async
wait
而不是创建新的线程/后台工作程序。
在我看来,在与
控件进行交互时使用Invoke从来都不是坏事。官方的答案是,这取决于谁调用了您的foo函数。它是主线程还是另一个线程

如果它是主线程(最好是创建控件的线程),则不需要调用。异步不影响这一点

以下是UI线程完成的,可以正常工作

public async void Button1_Clicked(object sender, ...)
{
     await Foo();
}
通常人们认为异步等待是由几个线程完成的。但事实并非如此。异步函数中的线程执行所有语句,直到遇到等待。它不是真正地等待等待等待的函数完成,而是在其调用堆栈中查看是否可以执行其他操作

这在(在页面上搜索异步)中有很好的解释。厨师没有等到面包烤好,而是开始煮鸡蛋。但它仍然是同一个厨师

当您看到在没有等待的情况下调用异步函数的代码时,线程将执行调用,直到遇到等待,并在未等待的调用之后执行语句,而不是什么都不做

private async void Button1_clicked(object sender, ...)
{
    var taskFoo = this.Foo()
    // because not await: the thread will do the things in Foo until it meets
    // an await. Then it returns back to do the next statements:

    DoSomething();

    // if this function has nothing more to do, or if it needs the result
    // of Foo, await Foo:
    await taskFoo;

    ProcessFooResult();
}
这个wait for taskFoo具有将控件返回给调用方(仍然是同一个线程)的效果,直到调用方等待为止。在这种情况下,控制权交给他的来电者,直到等待等

唯一涉及不同线程的时间是您主动启动它时,通常使用:

var myTask = Task.Run( () => DoSomething() );
// Because there is no await, your thread will do immediately the next
// statements until an await:

DoOtherThings();
await myTask();
现在DoSomething由另一个线程执行。如果需要访问UI控件,则需要调用required和Invoke


另一个关于async await的有用故事:

创建新线程/backgroundWorker是否意味着在外部线程上运行代码时需要使用invoke?即使我认为这很糟糕,我也没有找到在与ControlsYes交互时调用的替代方法,它确实。。。顺便说一下:
wait Task.Run(()=>{foo();})运行时不是异步的吗?如果您使用
wait Task.Run(foo())async wait
的目的是用于I/O操作(在操作等待来自I/O设备的响应时释放主线程)。在您的案例中,尝试在每个循环中考虑使用<代码>后台工作人员>代码>代码>进程更改< /代码>。