有关我的问题的一些信息:
我有一个Windows Forms应用程序,该应用程序具有可以并行计算很长时间的多线程。在计算这些线程时,修改UI元素(例如,标签,文本框,按钮等)并写入RichTextBox。
我有很多委托来进行线程安全调用和检查InvokeRequired很多次。
我有很多这样的方法:
private void AppendText(string text)
{
if(richTextBox.InvokeRequired)
{
Invoke(myDelegate, new object[] { text });
}
else
{
richTextBox.Append(text);
}
}
我的问题是:
这是从后台线程修改UI线程上的控件的一种好方法,还是我犯了一些体系结构错误?
答案 0 :(得分:1)
以下是一个简单的代码,用于说明let { compose, mapObjIndexed } = require('ramda')
const inc = (n: number) => n + 1
const inc2 = (n: number, count = 2) => n + count
const g = {
inc,
inc2,
}
const inc3 = (n: number) => n + 3
const g2: any = Object.keys(g).reduce(
(previousValue, key) => {
console.log('props', previousValue, key)
return {
...previousValue,
[key]: (...arg: any[]) => { return inc3(g[key](...arg)) },
}
},
{})
// const g2 = mapObjIndexed((action: any) => compose(inc3, action))(g)
// => So you can use
// But in this case g2 is any, so I have to define type of g2.
// How can I define type of g2(in this case any) depend on the g
console.log('>>', g2.inc(2), g2.inc2(5)) // 6 and 10
Async-Await
public async Task Main()
{
var result = await Background("Test");
// Update Ui here, its on Ui thread
}
// Executed Asynchronously in the Background
public async Task<string> Background(string text)
{
return await Task.FromResult(text);
}
方法是异步处理的,如果它在网络上像db调用一样,则不需要线程池线程,如果在内存中,它将使用线程池线程Background
方法,结果就可以在控件上自动更新为Ui线程Background
处理数据,然后更新结果Task Parallel Library
仍然是阻塞呼叫,尽管它将释放呼叫上下文,这意味着Ui不会冻结,仍然可以访问,但是可以使用await
进行非阻塞呼叫,返回时可以用来更新Ui,尽管您始终必须阻止Main / Ui线程退出Task.Run