我正在使用此方法以编程方式实例化Web浏览器,导航到URL并在文档完成时返回结果.
如果文档加载时间超过5秒,我将如何停止Task并GetFinalUrl()返回null?
我见过许多使用a的例子,TaskFactory但我无法将其应用于此代码.
private Uri GetFinalUrl(PortalMerchant portalMerchant)
{
SetBrowserFeatureControl();
Uri finalUri = null;
if (string.IsNullOrEmpty(portalMerchant.Url))
{
return null;
}
Uri trackingUrl = new Uri(portalMerchant.Url);
var task = MessageLoopWorker.Run(DoWorkAsync, trackingUrl);
task.Wait();
if (!String.IsNullOrEmpty(task.Result.ToString()))
{
return new Uri(task.Result.ToString());
}
else
{
throw new Exception("Parsing Failed");
}
}
// by Noseratio - http://stackoverflow.com/users/1768303/noseratio
static async Task<object> DoWorkAsync(object[] args)
{
_threadCount++;
Console.WriteLine("Thread count:" + _threadCount);
Uri retVal = null;
var wb = new WebBrowser();
wb.ScriptErrorsSuppressed = …Run Code Online (Sandbox Code Playgroud) .net c# console-application webbrowser-control task-parallel-library
例如,我有以下简单的HTML页面,其中<span>[SOME FIELD]</span>重复多次以弥补大约200K的文件大小:
<!DOCTYPE html>
<html>
<head>
</head>
<body editableContent="true">
<span>[SOME FIELD]</span>
<span>[SOME FIELD]</span>
...
<span>[SOME FIELD]</span>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
随着内容的增长,编辑体验变得非常滞后.输入或编辑内容几乎是不可能的.
这是一个完整的repro案例.要查看我的意思,只需将光标移动到可编辑内容的末尾并尝试编辑即可.在IE和Chrome下它落后很长时间,几乎不可能打字.但它在Firefox下运行良好.
问题:我需要在IE下合理快速地运行它.
到目前为止,我已经接近IE8模拟(带<meta http-equiv="X-UA-Compatible" content="IE=8">),所以这是有效的(在IE下).
但是,我也需要支持IE=edge.任何关于如何实现这一点的建议将不胜感激.国际海事组织,这是一个错误(我提交这里IE和这里的Chrome),但我在寻找什么解决办法.
更新后,为使用HTML文档模式在独立IE浏览器或托管WebBrowser控件的自定义应用程序中加载的任何解决方案提供了赏金IE=edge.
html javascript internet-explorer webbrowser-control contenteditable
我有一些不可为 null 的字段,我想在从构造函数调用的辅助方法中初始化这些字段,以减少构造函数内部的混乱:
private FlowLayoutPanel _flowPanel;
private ComboBox _printersComboBox;
//...
public PrintSettingsView(IServiceProvider serviceProvider, IPrintSettings printSettings)
{
InitializeComponent();
PostInitializeComponent(); // this is where _flowPanel etc get initialized
// ...
}
Run Code Online (Sandbox Code Playgroud)
如何避免类似的警告Non-nullable field '_flowPanel' must contain a non-null value when exiting constructor. Consider declaring the field as nullable?
到目前为止我想到的最好的主意是:
public static void Assert([DoesNotReturnIf(false)] bool condition)
{
if (!condition) throw new InvalidOperationException();
}
public PrintSettingsView(IServiceProvider serviceProvider, IPrintSettings printSettings)
{
InitializeComponent();
PostInitializeComponent();
Assert(_flowPanel != null);
Assert(_printersComboBox != null);
//...
}
Run Code Online (Sandbox Code Playgroud)
当有很多田地时,它仍然变得混乱。还有比这更好的事情吗?
这是一个 …
在Test_Click下面是代码的简化版本,其可以运行在一个UI线程(与WindowsFormsSynchronizationContext):
void Test_Click(object sender, EventArgs e)
{
var task = DoNavigationAsync();
task.ContinueWith((t) =>
{
MessageBox.Show("Navigation done!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)
我应该明确指定TaskScheduler.FromCurrentSynchronizationContext()以确保在同一UI线程上执行延续操作吗?或者ContinueWith自动捕获执行上下文(因此,TaskScheduler在这种情况下使参数多余)?
我认为默认情况下不会这样做(不像await),但到目前为止我找不到在线资源来确认这一点.
这是一个简单的WinForms应用程序:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
var ts = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(async () =>
{
Debug.WriteLine(new
{
where = "1) before await",
currentTs = TaskScheduler.Current,
thread = Thread.CurrentThread.ManagedThreadId,
context = SynchronizationContext.Current
});
await Task.Yield(); // or await Task.Delay(1)
Debug.WriteLine(new
{
where = "2) after await",
currentTs = TaskScheduler.Current,
thread = Thread.CurrentThread.ManagedThreadId,
context …Run Code Online (Sandbox Code Playgroud) 默认情况下,.NET对象是自由线程的.如果通过COM封送到另一个线程,它们总是被封送到自己,无论创建者线程是否是STA,并且无论其ThreadingModel注册表值如何.我怀疑,他们聚合了Free Threaded Marshaler(有关COM线程的更多细节可以在这里找到).
我想让我的.NET COM对象在封送到另一个线程时使用标准的COM marshaller代理.问题:
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var apt1 = new WpfApartment();
var apt2 = new WpfApartment();
apt1.Invoke(() =>
{
var comObj = new ComObject();
comObj.Test();
IntPtr pStm;
NativeMethods.CoMarshalInterThreadInterfaceInStream(NativeMethods.IID_IUnknown, comObj, out pStm);
apt2.Invoke(() =>
{
object unk;
NativeMethods.CoGetInterfaceAndReleaseStream(pStm, NativeMethods.IID_IUnknown, out unk);
Console.WriteLine(new { equal = Object.ReferenceEquals(comObj, unk) });
var marshaledComObj = (IComObject)unk;
marshaledComObj.Test();
}); …Run Code Online (Sandbox Code Playgroud) 我真的很挣扎相对符号链接上WSL2它们在Linux的本地文件系统创建的,我想,当通过共享点访问文件\\wsl$\distro-name\whatever-他们只是打破。
我已经wsl2在我的 Windows10 中激活了。我有一个Ubuntu-20.04:
损坏的符号链接禁止我在“从 Windows 中的 IDE 编辑”时无缝地“在 wsl2 中执行”。
实际用例(但不限于):开发两个集成项目:一个带有应用程序的 repo 和另一个与库一起存在的 repo。该应用程序符号链接库:
/files/repos/my-nice-app/files/repos/my-nice-libmy-nice-app/libs/my-nice-lib 是一个符号链接 ../../my-nice-lib\\wsl$\Ubuntu-20.04\files\repos\my-nice-app通过此设置,该位置\\wsl$\Ubuntu-20.04\files\repos\my-nice-app\libs\my-nice-lib应映射到\\wsl$\Ubuntu-20.04\files\repos\my-nice-lib。
但它不起作用。IDE 中的所有代码完成都搞砸了,因为符号链接没有很好地解映射并且 IDE 无法读取库的类和定义。
每当我在 NTFS 文件系统中从 linux 创建符号链接时,它都会在 windows 中正确解码。
反面相同:如果我从 windows(使用 CMD 和mklink或 Powershell 使用New-Item)创建链接,它们会 …
我正在编写一个多人游戏服务器,我正在研究新的C#async/await功能可以帮助我的方法.服务器的核心是一个循环,它尽可能快地更新游戏中的所有演员:
while (!shutdown)
{
foreach (var actor in actors)
actor.Update();
// Send and receive pending network messages
// Various other system maintenance
}
Run Code Online (Sandbox Code Playgroud)
这个循环需要处理数千个演员并每秒更新多次以保持游戏顺利运行.有些演员偶尔会在更新函数中执行缓慢的任务,例如从数据库中获取数据,这是我想要使用异步的地方.一旦检索到该数据,actor就想要更新游戏状态,这必须在主线程上完成.
由于这是一个控制台应用程序,我计划编写一个SynchronizationContext,它可以将挂起的委托分派给主循环.这允许这些任务在完成后更新游戏,并允许将未处理的异常抛入主循环.我的问题是,如何编写异步更新功能?这非常好用,但打破了不使用async void的建议:
Thing foo;
public override void Update()
{
foo.DoThings();
if (someCondition) {
UpdateAsync();
}
}
async void UpdateAsync()
{
// Get data, but let the server continue in the mean time
var newFoo = await GetFooFromDatabase();
// Now back on the main thread, update game state
this.foo = newFoo;
}
Run Code Online (Sandbox Code Playgroud)
我可以使Update()异步并将任务传播回主循环,但是:
我怎么办这些我无法等待的任务?我唯一想知道他们已经完成的时间是关闭服务器的时候,但是我不想收集可能需要数星期更新的每一项任务.
c# asynchronous synchronizationcontext task-parallel-library async-await
显然,使用嵌套using语句时可能会丢失一些异常.考虑这个简单的控制台应用
using System;
namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;
public Throwing(int n)
{
this.n = n;
}
public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}
class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
} …Run Code Online (Sandbox Code Playgroud) 我刚刚注意到,使用.NET 4.5,每个Dispatcher.BeginInvoke/ InvokeAsync回调都是在它自己非常独特的同步上下文(一个实例DispatcherSynchronizationContext)上执行的.这种变化背后的原因是什么?
以下简单的WPF应用程序说明了这一点:
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Action test = null;
var i = 0;
test = () =>
{
var sc = SynchronizationContext.Current;
Dispatcher.CurrentDispatcher.InvokeAsync(() =>
{
Debug.Print("same context #" + i + ": " +
(sc == SynchronizationContext.Current));
if ( i < 10 )
{
i++;
test();
}
});
};
this.Loaded += …Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×6
async-await ×3
asynchronous ×2
.net-core ×1
com ×1
com-interop ×1
html ×1
javascript ×1
linux ×1
non-nullable ×1
symlink ×1
windows ×1
windows-subsystem-for-linux ×1
wpf ×1
wsl-2 ×1