我正在尝试多线程,但是我无法弄清楚为什么下面的代码会在调用task.Execute()时阻止UI?
public class Task<TRes>
{
private Func<TRes> _func;
public Task(Func<TRes> func)
{
_func = func;
}
public TRes Execute()
{
var iasync = _func.BeginInvoke(null, null);
return _func.EndInvoke(iasync);
}
}
我不是要特别解决任何问题。只是想知道为什么UI在遇到Thread.Sleep时阻塞,即使当前线程(被置于“睡眠”的线程)是一个ThreadPool线程(而不是主UI线程)。下面是一个使用Task类的按钮单击事件。
var task = new Task<string>(() =>
{
var start = DateTime.Now;
var isBackGround = Thread.CurrentThread.IsBackground ;
var isThreadPool = Thread.CurrentThread.IsBackground;
Thread.Sleep(5000);
return String.Format("Start {0} : End {1}", start, DateTime.Now);
}
);
this.label1.Text = task.Execute();
答案 0 :(得分:1)
问题是调用EndInvoke
会阻塞调用线程,直到函数完成执行。你正在做的是产生一个工作线程来执行你的_func
然后阻塞直到那个工人完成。我建议使用BeginInvoke
的回调参数。如果您正在做GUI内容,请不要忘记Dispatcher。
考虑到这一点,我不建议开始使用GUI进行多线程处理,因为这可能是一个真正的痛苦。从控制台应用程序开始,这样您就可以了解整个多线程的事情,然后转移到GUI,这会让事情变得痛苦。
void Main()
{
var cookies = new IAsyncResult[10];
Action action = delegate
{
// I'm going to print out a bunch of numbers here
for (int i = 0; i < 100; ++i)
Console.WriteLine(i);
}
for (int i = 0; i < cookies.Length; ++i)
cookies[i] = action.BeginInvoke(null, null);
// with all 10 threads executing, you'll see numbers print out in some crazy,
// unpredictable order...this line will come out somewhere in the mess (or maybe
// before it...who knows?)
Console.WriteLine("All threads started!");
// we wait for each of the workers to finish executing here:
foreach (var c in cookies)
action.EndInvoke(c);
// and this will always be printed last, thereby demonstrating that EndInvoke
// causes the calling thread to wait for the action to finish
Console.WriteLine("Done!");
}
答案 1 :(得分:0)
我知道这不能直接回答你的问题,但我只是想指向System.Threading.Tasks命名空间,如果你使用的是.Net 4.0。任务(T)确实有很好的记录,并按预期执行。
-Josh