C# 为什么在离开方法之前使用变量会自行处理? 使用木偶手; 使用制度; 使用System.Threading.Tasks; 名称空间视频处理器 { 公共类视频主机 { 私有静态bool是\u HTTPS\u URL(字符串URL) { Uri结果; bool result=Uri.TryCreate(url,UriKind.Absolute,out-uriResult)&&(uriResult.Scheme==Uri.UriSchemeHttps); 返回结果; } #区域浏览器代码 专用静态异步任务FectchBrowserIfItIsNotThere() { var browserFetcher=新的browserFetcher(); 等待browserFetcher.DownloadAsync(); } 内部静态异步任务GetPageAsync(字符串url,bool isPageInvisible=true,操作) { 如果(!Is_HTTPS_URL(URL)) { 抛出新的ArgumentException($“url{url}}不是https url。”); } 等待fectchbrowserifitisnothere(); wait using var browser=wait puppeter.LaunchAsync( 新的启动选项{Headless=isPageInvisible}); 使用var page=await browser.NewPageAsync()等待; 等待page.GoToAsync(url); 行动(第页); 返回页面; } } } //锅炉板代码 异步静态void Main() { 动作动作=(第页)=>Foo(第页); 等待GetPageAsync(“https://google.com",虚假,行为),; } 公共静态异步任务Foo(第p页){ 等待p.EvaluateExpression(//填充谷歌搜索栏);//第一行 等待p.EvaluateExpression(//单击搜索按钮”);//第二行 wait p.waitForNavigationSync();//第三行 等待p.EvaluateExpression(“警报(“hi”)”)//第四行 }

C# 为什么在离开方法之前使用变量会自行处理? 使用木偶手; 使用制度; 使用System.Threading.Tasks; 名称空间视频处理器 { 公共类视频主机 { 私有静态bool是\u HTTPS\u URL(字符串URL) { Uri结果; bool result=Uri.TryCreate(url,UriKind.Absolute,out-uriResult)&&(uriResult.Scheme==Uri.UriSchemeHttps); 返回结果; } #区域浏览器代码 专用静态异步任务FectchBrowserIfItIsNotThere() { var browserFetcher=新的browserFetcher(); 等待browserFetcher.DownloadAsync(); } 内部静态异步任务GetPageAsync(字符串url,bool isPageInvisible=true,操作) { 如果(!Is_HTTPS_URL(URL)) { 抛出新的ArgumentException($“url{url}}不是https url。”); } 等待fectchbrowserifitisnothere(); wait using var browser=wait puppeter.LaunchAsync( 新的启动选项{Headless=isPageInvisible}); 使用var page=await browser.NewPageAsync()等待; 等待page.GoToAsync(url); 行动(第页); 返回页面; } } } //锅炉板代码 异步静态void Main() { 动作动作=(第页)=>Foo(第页); 等待GetPageAsync(“https://google.com",虚假,行为),; } 公共静态异步任务Foo(第p页){ 等待p.EvaluateExpression(//填充谷歌搜索栏);//第一行 等待p.EvaluateExpression(//单击搜索按钮”);//第二行 wait p.waitForNavigationSync();//第三行 等待p.EvaluateExpression(“警报(“hi”)”)//第四行 },c#,.net,idisposable,using-statement,puppeteer-sharp,C#,.net,Idisposable,Using Statement,Puppeteer Sharp,我遇到一个问题,当我将页面变量发送给在页面变量中执行的操作时,会导致页面或浏览器变量被释放。根据我对使用的理解,只有在我离开函数的括号时才会发生这种情况。我已经阅读了Microsoft关于的文档,但我找不到任何东西告诉我,页面变量在进入使用变量所在的函数中的另一个函数时会自行处理 此外,有时代码能够计算函数的一些表达式,但通常在第三个表达式之前失败。但是,如果我一步一步地调试和运行,它总是在第一行失败。这让我相信这是一个处置问题 如果有人想知道为什么我没有将using frombrowser和p

我遇到一个问题,当我将页面变量发送给在页面变量中执行的操作时,会导致页面或浏览器变量被释放。根据我对使用的理解,只有在我离开函数的括号时才会发生这种情况。我已经阅读了Microsoft关于的文档,但我找不到任何东西告诉我,页面变量在进入使用变量所在的函数中的另一个函数时会自行处理

此外,有时代码能够计算函数的一些表达式,但通常在第三个表达式之前失败。但是,如果我一步一步地调试和运行,它总是在第一行失败。这让我相信这是一个处置问题


如果有人想知道为什么我没有将using frombrowserpage变量从浏览器中删除并自己处理掉,我有两个原因。第一,我没有处理非托管代码的经验,当我尝试将dispose添加到终结器/析构函数时,它不起作用;第二,我不想编写代码来完成该语言已经为我做的事情。

问题是使用Action而不是Func

动作总是返回一个空白。由于Action调用的函数是异步方法,但没有发送方法的输出,因此会导致调用Action的函数退出,从而释放未管理的资源。Func会保留输出,以便等待输出,从而阻止主线程直到完成,从而防止过早释放非托管资源

//Boiler Plate code
async static void Main()
{
  Action<Page> action = (page) => Foo(page);
  await GetPageAsync("https://google.com", false , action);
}
public static async Task Foo(Page p){ 
   await p.EvaluateExpression("//fill google search bar"); //first line
   await p.EvaluateExpression("//click search button");  //second line
   await p.WaitForNavigationAsync(); //third line
   await p.EvaluateExpression("alert("hi")"); //fourth line
}
async static void Main()
{
Func Func=(FileStream fs)=>Foo(fs);//函数的输入是FileStream,输出是Task
Action Action=(FileStream fs)=>Foo(fs);//等效于Func
使用var fs=new FileStream();
//action(fs);//如果主线程在此之前完成,则此操作可能失败
wait func(fs);//这将成功,因为主线程被阻塞,直到完成
}
异步静态任务Foo(FileStream fs)=>wait fs.SomeLongAsyncMethod();

请发布您的真实代码。显然,在
void Foo
中使用
wait
关键字会导致编译器错误。如果
void Foo
实际上是
async void Foo
,那么您(可能)在
GetPageAsync
方法的执行生命周期之外使用了该页。请指定失败的含义以及不等待
Foo
的“第一行”。尝试
Func
而不是
Action
。不,因为你基本上是在说“去享受生活吧,富,你现在自由了!”然后忘记它,继续执行。请参阅。
//Boiler Plate code
async static void Main()
{
  Action<Page> action = (page) => Foo(page);
  await GetPageAsync("https://google.com", false , action);
}
public static async Task Foo(Page p){ 
   await p.EvaluateExpression("//fill google search bar"); //first line
   await p.EvaluateExpression("//click search button");  //second line
   await p.WaitForNavigationAsync(); //third line
   await p.EvaluateExpression("alert("hi")"); //fourth line
}
async static void Main()
{
   Func<FileStream,Task> func = (FileStream fs) => Foo(fs); //Input to function is FileStream and Output of Function is Task
   Action<FileStream> action = (FileStream fs) => Foo(fs); //Equivalent to Func<FileStream , void>
   using var fs = new FileStream();
   //action(fs); //This can fail if the main thread is finished before it
   await func(fs); //This will succeed since the main thread is blocked till completion

}
async static Task Foo(FileStream fs) => await fs.SomeLongAsyncMethod();