当ThreadUI进入睡眠状态时,C#在指定的UIThread(不是延续)中运行任务会阻塞

时间:2018-09-10 17:56:04

标签: c# timeout task blocking ui-thread

我正在开发一个需要对不同服务器进行调用的应用程序:其中一些是ActiveX(或COM)服务器,其他可以在ThreadPool中运行。由于这些服务器的提供商来自不同的公司,并且其中一些服务器正在使用(确实)过时的技术(包装在.Net上的C / C ++ dll),因此它们没有一致的超时机制(如果没有的话)。

我开始使用Task和不同文章中建议的超时来实现异步调用(感谢Reed Copsey,Jr.,Stephen Toub和Stephen Cleary)。

在“客户端”端(对于测试应用程序是MainForm),我有:

int结果=等待sB.TheForm.F2Async(“ TEST”,1.5,CombinedCTS);

其中:

    - sB.TheForm: is the WinForm that runs in the second UIThread. The MainForm spun the "TheForm" Form in a different thread making an UIThread.
    - "TEST", 1.5: are the actual parameters 
    - combinedCTS is of CancellationTokenSource type 

在“服务器”端,F2Async函数将第二个UIThread中的F2函数作为TASK(工作任务)进行调度,并快速异步地进行:)调度

var completedTask = await Task.WhenAny(workingTask, Task.Delay(nTimeoutMilisec));

要在其他UI线程中安排任务,请使用

var workingTask = Task.Factory.StartNew<int>(
                  () => F2(s1, d1), 
                  combinedCTS.Token, 
                  TaskCreationOptions.DenyChildAttach, 
                  TaskSchedulerForm);

其中:

    - F2() is the synchronous function (the ActiveX function)
    - TaskSchedulerForm: is initialized in the LOAD event handler of the second UIThread as
TaskSchedulerForm = TaskScheduler.FromCurrentSynchronizationContext();

如果F2函数进入睡眠状态(或阻止),为什么Task.Factory.StartNew阻止?

由于没有等待StartNew(函数F2Async)的调用,因此代码应在主线程ui中继续,直到WhileAny任务的等待。

我尝试了不同的方法来运行await Task.WhenAny(...)。当F2阻塞时,仅在F2完成后才执行RunNew之后的语句。

F2运行第二个(所需的)UI线程。如果函数F2没有阻塞,则在Task.WhenAny开始等待时它仍在运行-很好,因为现在我可以在出现超时的情况下强制继续运行。

0 个答案:

没有答案