我对多线程非常陌生,因此,我确信我的整个问题很可能是错的,但这对我来说更适合学习如何正确完成,所以我希望你能做到这一点。 ;请原谅和任何解释设置在"白痴"水平将非常感谢!!!!
假设我的WinForm外部有以下类:
public class test
{
public void RunOnSeparateThread()
{
// Some function that takes an AsyncCallback as a parameter and runs Asynchronously
// Returns IAsyncResult
foo(m_asyncCallback);
}
private AsyncCallback m_asyncCallback = new AsyncCallback(AsyncComplete);
private static void AsyncComplete(IAsyncResult result)
{
// Whatever disposal stuff needs to be done, etc.
}
}
现在,我想要做的是在我的winform上有一个按钮,当按下时:
RunOnSeparateThread
进程(不占用GUI线程)然后,当异步过程完成时:
AsyncComplete
类Test
方法
Form
类中的其他一些内容)正如我所说,这对我来说都是全新的。我想象的可能是在表单上创建一个AsyncCallback委托并将其传递给我的类(作为属性??)并在最后运行AsyncComplete
方法,但它看起来这可能是非常糟糕的编程。
这样做的最佳/正确方法是什么 - 请理解我是这类东西的主要新手,所以我非常感谢任何链接/解释,以便了解正确的多方式-thread用于此类场景。
此外,虽然这是用C#编写的,但我在VB和C#中也同样适用,所以任何答案都会非常感激。
感谢!!!
答案 0 :(得分:2)
除非您的要求是使用旧的.Net框架版本,否则我建议您使用TPL而不是过时的APM
方法。但回到这个问题。大多数UI框架不允许从非主(非UI)线程进行UI修改。因此,您应该使用Invoke方法将更新发布到UI线程循环(或BeginInvoke以异步方式执行委托)。使用TPL
一切都非常简单:
void button_Click(object sender, EventArgs e)
{
button.Enabled = false;
Task.Factory.StartNew(() =>
{
//long-running stuff
}).ContinueWith((result) =>
{
button.Enabled = true;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
请注意,您提出的问题实际上过于宽泛,最好在WinForms
中以异步方式阅读有关执行任务的文章。
修改强>
如果您无法控制foo
,则代码可能如下所示:
void button_Click(object sender, EventArgs e)
{
button.Enabled = false;
IAsyncResult asyncResult = foo(...);
Task.Factory.FromAsync(asyncResult, (result) =>
{
button.Enabled = true;
}, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}