Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#_Multithreading_Textbox_Parallel Processing_Deadlock - Fatal编程技术网

C# 冻结我的表格

C# 冻结我的表格,c#,multithreading,textbox,parallel-processing,deadlock,C#,Multithreading,Textbox,Parallel Processing,Deadlock,对于Form1.cs ... delegate void SetTextCallback(string text); ... public void setText(string s) { if (this.textbox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(setText); this.Invoke(d, new object[] { s }); }

对于Form1.cs

...
delegate void SetTextCallback(string text);
...

public void setText(string s)
{
    if (this.textbox1.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(setText);
        this.Invoke(d, new object[] { s });
    }
    else
    {
        textbox1.AppendText(s + Environment.NewLine);
        Application.DoEvents();
    }
}
...
private void btn_Click(object sender, eventArgs e)
{
     Test t = new Test();
     t.run();
}
和Test.cs

...
public void run()
{
    Parallel.ForEach(list, test =>
    {
        DoSomething(test);
        Form1.setText(test + "done!");
    }
}
...
在我运行程序后,它总是冻结。 我搜索了一下我的问题,发现是因为死锁问题。
如何解决此问题?

您是对的,这是一个死锁问题

Parallel.ForEach
阻塞,直到处理完
列表中的所有项目,并且您使其在UI线程上运行,因此现在UI线程被阻塞

然后调用
Form1.setText(test+“done!”)
setText
(顺便说一句,
s
应该是大写)调用
this.Invoke
,它将阻止调用,直到处理完Invoke调用为止。但是,因为我们在
Parallel.ForEach
上阻止了UI线程,因此它将永远不会被处理,而您只是死锁了

解决这个问题的方法是将
并行。ForEach
也调用它自己的线程,这样就不会阻塞UI线程

public void run()
{
    Task.Factory.StartNew(() => Parallel.ForEach(list, test =>
    {
        DoSomething(test);
        Form1.setText(test + "done!");
    }), TaskCreationOptions.LongRunning);
}
您还可以通过将
this.Invoke
更改为
this.BeginInvoke
1来提高性能,这样文本更新也不会阻塞。但是,如果您只将
BeginInvoke
更改为您的程序,并使
保持并行。在UI线程上,ForEach
可能不再死锁,但您的UI仍将冻结并说
没有响应
,直到
Parallel.ForEach
完成



一,。在其他任何地方,如果您调用
BeginXxxxx
,则必须调用
EndXxxxx
,但是
BeginInvoke
对从
Control
派生的类进行调用,并且您不需要调用
EndInvoke

DoSomething
在哪里,它是否与
textBox1
有关请不要在问题标题中添加标记,这是底部标记的用途。哦,实际上我收到错误消息:无法将lambda表达式转换为类型“System.Threading.Tasks.ParallelOptions”,因为它不是委托类型on变量“test”。我该怎么办?已更改},TaskCreationOptions.LongRunning);到}),TaskCreationOptions.LongRunning);