Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当在客户端超时时取消控制器操作时,ASP.NET MVC3应用程序将如何调用某些代码?_C#_Asp.net_.net_Asp.net Mvc 3 - Fatal编程技术网

C# 当在客户端超时时取消控制器操作时,ASP.NET MVC3应用程序将如何调用某些代码?

C# 当在客户端超时时取消控制器操作时,ASP.NET MVC3应用程序将如何调用某些代码?,c#,asp.net,.net,asp.net-mvc-3,C#,Asp.net,.net,Asp.net Mvc 3,有一个ASP.NET MVC3应用程序,其中一些控制器操作使用外部机制来处理输入数据。输入数据首先保存到一个临时文件中,然后运行一个外部程序,并在命令行中传递临时文件的路径。这是使用System.Diagnostics.Processclass完成的 外部程序通常会很快退出—比启动后的一秒钟要早,因此没有问题,只需使用Process.WaitForProcessExit()和dispose TheProcess对象等待其完成即可 如果外部程序挂起并且没有及时退出,那么它会变得更加困难。这种情况很

有一个ASP.NET MVC3应用程序,其中一些控制器操作使用外部机制来处理输入数据。输入数据首先保存到一个临时文件中,然后运行一个外部程序,并在命令行中传递临时文件的路径。这是使用
System.Diagnostics.Process
class完成的

外部程序通常会很快退出—比启动后的一秒钟要早,因此没有问题,只需使用
Process.WaitForProcessExit()
和dispose The
Process
对象等待其完成即可

如果外部程序挂起并且没有及时退出,那么它会变得更加困难。这种情况很少发生,但当它发生时,
Process.WaitForProcessExit()
也会挂起,控制器操作会运行一段时间,但随后客户端超时,控制器操作被取消,但我无法找到会导致外部程序强制终止的方法。我当然可以使用
Process.Kill()
,但我必须将此调用连接到某个地方,以便在由于客户端超时而取消控制器操作时调用它

我试图重写Controller.OnException(),但在这种情况下似乎没有调用它


如何更改ASP.NET MVC3代码,使其在客户端超时时调用某些自定义代码(如外部程序终止)?

我已根据基于任务的注释检查了解决方案-这在执行阻塞操作时非常有用。您可以避免阻塞调用
WaitForProcessExit()
,并创建更简单的解决方案

解决方案是以包装器的形式

public enum SafeProcessState { Exit = 1, Killed = 2 }

public class SafeProcess
{
    private readonly Process process;
    private readonly Func<bool> killPredicate;

    public SafeProcess(Func<bool> killPredicate, Process process)
    {
        this.killPredicate = killPredicate;
        this.process = process;
    }

    public async Task<SafeProcessState> WaitAsync()
    {
        var state = SafeProcessState.Exit;

        while (true) 
        {
            await Task.Delay(100);
            if (this.killPredicate())
            {
                state = SafeProcessState.Killed;
                if (this.process.HasExited == false)
                {
                    this.process.Kill();
                }
                break;
            }
            else if (this.process.HasExited) 
            {
                break;
            }
        }

        return state;
    }
}
它基本上(每100毫秒检查一次)等待进程退出或客户端断开连接,并返回有关退出原因的信息-
exit
Killed

如果用户已断开连接,则终止进程


使用
async/await Task.Delay
可以确保释放执行线程,这样做100毫秒纯粹是出于性能原因

注意:您可以进入终止已经退出的进程的场景,这将引发异常(进程和asp net操作之间存在并发)。您需要在进程执行和
.Kill()
之间进行一些同步。。。或者,您可以将呼叫包装为try/catch。

如果您选择“尝试/捕获-忘记”方案,一定要记录情况。

解决方案不太清楚,但如何:您可以找到一种方法将
进程。WaitForProcessExit()
转换为常见的
任务
。然后可以使用
var timeoutTask=Task.Delay(30*1000);如果(wait Task.WhenAny(Task,timeoutTask)=timeoutTask){…}
@vasily.sib,则代码似乎没有外部进程的“强制终止”。
public async ...... ActionName()
{
  var process = Process.Start("....");
  var wrapper = new SafeProcess(() => HttpContext.Current.Response.IsClientConnected == false, process);

 var state = await wrapper.WaitAsync();
}