bor*_*egg 1 .net c# multithreading asynchronous
我觉得这个问题的答案是由于我对线程如何工作的概念不正确,但是这里有.
private void button1_Click(object sender, EventArgs e)
{
this.TestMethodAsync(); // No await, i.e. fire and forget
// ** Some code here to perform long running calculation (1) **
}
private async Task TestMethodAsync()
{
// Some synchronous stuff
await Task.Delay(1000);
// ** Some code here to perform long running calculation (2) **
}
Run Code Online (Sandbox Code Playgroud)
首先,我不会"发射并忘记"这样的异步方法(我会使用Task.Run),但我遇到的代码确实存在,我试图了解效果是什么.
在使用a的WinForms应用程序中,WindowsFormsSynchronizationContext我对async和await的理解告诉我,当我单击button1时,该方法将在UI线程上同步启动.它会TestMethodAsync同步调用和运行,直到它到达等待状态.然后它将捕获上下文,启动Task.Delay任务,并将控制权交给调用者.由于我们没有等待此调用,因此button1_Click将继续在UI线程上开始执行计算(1).
在某些时候,Task.Delay(1000)将完成.然后,继续将TestMethodAsync使用捕获的上下文运行方法的其余部分,在这种情况下,意味着将继续在UI线程上运行.现在开始执行计算(2).
我们现在有两个独立的代码段,希望同时在同一个线程(UI线程)上运行.我对此的调查似乎表明,线程在代码的两个部分之间来回切换,以便同时执行它们.
题:
我对这里到底发生了什么感到困惑.如何在已经运行其他代码的线程上恢复?是什么迫使线程在想要运行的两段代码之间切换?通常,当您尝试在已经运行其他代码的线程上恢复时会发生什么?
(我想这与我的点击事件首先在UI线程上运行的方式没有任何不同,因为我知道它在UI线程上运行,我知道UI线程也在做其他事情,但是我之前没有真正考虑过它.)
这是你不明白的秘密:我给你Windows消息循环
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
while(TRUE)
{
bRet = GetMessage(&msg, NULL, 0, 0);
if (bRet <= 0) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)
这是您申请的实际"主要"; 你只是看不到它,因为它隐藏在幕后.
无法想象一个更简单的循环.它从队列中获取消息.如果没有更多消息,则必须完成该程序.如果有消息,则它运行标准消息转换并调度消息,然后继续运行.
如何在已经运行其他代码的线程上恢复?
事实并非如此."在运行其他代码的线程上恢复"实际上是在队列中放入一条消息.DispatchMessage正在同步调用"其他代码".完成后,它返回循环,轮询队列,消息指示接下来需要分派的代码.然后它会同步运行,直到它返回循环.
是什么迫使线程在想要运行的两段代码之间切换?
没有.这不会发生.
通常,当您尝试在已经运行其他代码的线程上恢复时会发生什么?
描述需要运行什么延续的消息排队等候.
我想这与我的点击事件首先在UI线程上运行的方式没有任何不同,因为我知道它在UI线程上运行,我知道UI线程也在做其他事情,但我之前没有真正想过这个.
开始考虑它.
点击事件完全相同.你的计划正在做点什么; 你点击鼠标; 点击处理程序不会中断UI线程并开始在其上运行新工作.相反,消息排队,当您的UI线程控制返回到消息循环时,最终会处理单击; DispatchMessage导致通过Windows窗体中的某种机制调用Button1_OnClick.这是的WinForms什么是 ; 用于将Windows消息转换为对C#方法的调用的机制.
但你已经知道了.您知道当事件驱动的程序执行长时间运行的同步操作时,UI会冻结,但最终会处理该单击事件.你是怎么想的那样发生的?您必须在某种程度上理解他们排队等待以后处理,对吧?
练习:做DoEvents什么?
练习:鉴于您现在所知道的:如果您DoEvents在循环中调用以取消阻止UI,可能会出现什么问题?
练习:与GUI应用程序有何await不同DoEvents?
| 归档时间: |
|
| 查看次数: |
242 次 |
| 最近记录: |