Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.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# 新线程正在作为UI线程运行_C#_Multithreading_Winforms_User Interface - Fatal编程技术网

C# 新线程正在作为UI线程运行

C# 新线程正在作为UI线程运行,c#,multithreading,winforms,user-interface,C#,Multithreading,Winforms,User Interface,我有一个表单DisplayImagesForm,它在构造函数中调用函数loadImages: public ImageScraperForm(string query, RichTextBox textBox) { InitializeComponent(); this.query = query; loadImages(); } 然后loadImages函数在末尾创建一个新线程: { ... Thread thread = new Thread(readN

我有一个表单DisplayImagesForm,它在构造函数中调用函数loadImages:

public ImageScraperForm(string query, RichTextBox textBox)
{
    InitializeComponent();
    this.query = query;
    loadImages();
}
然后loadImages函数在末尾创建一个新线程:

{
   ...
   Thread thread = new Thread(readNextImage);
   thread.Start();
}

问题在于,该线程似乎不像UI线程那样作为不同的线程运行。readNextImage方法从服务器加载图像,这需要一些时间——加载图像时会阻塞整个表单。这是不正常的,因为线程应该与UI线程分开运行。readNextImage函数还可以修改UI元素,而无需调用MethodInvokerDelegate-不会引发异常。

如果您试图通过internet下载图像并在WinForm控件中显示它;你完全错了

不要在表单构造函数中进行任何冗长的处理;这将使您的表单无响应。如果要在UI中显示某些内容,则应在窗体的Paint事件处理程序中显示。如果你试图通过互联网下载东西,你应该使用wait,而不是线程。线程使用一个CPU核心,由于互联网的速度比CPU慢几个数量级,您将立即阻止它

正确的方法是在需要时使用wait加载文件。如果在启动Load事件处理程序时需要它,那么这是一个不错的选择

private async void YourForm_Load(object sender, EventArgs e)
{
    using (var c = new HttpClient())
    using (var resp = await c.GetAsync(@"http://uri/to/image.jpg"))
    using (var content = resp.Content)
    using (var s = await content.ReadAsStreamAsync())
    {
        _img = new Bitmap(s);
    }

    YourControl.Invalidate();
}

private void YourForm_Paint(object sender, PaintEventArgs e)
{
    if (_img != null)
        DrawToYourControl(_img);
}

从一个线程中获取交互式结果确实很困难。有更简单的方法可以做到这一点,但我们需要知道readNextImage的功能。它做文件或网络I/O吗?你应该使用wait。它是执行繁重的计算还是程序生成?您最好使用。这是Windows窗体。readNextImage进行网络I/O。没有繁重的计算,它只需下载图像作为流并在图片框中显示。您是否尝试创建计时器,如果该计时器在线程终止前熄灭,它会向您发送一条控制台消息,例如“未完成”,这样您就可以知道线程正在工作,但这项工作的成本比您想象的要高。我曾考虑在程序执行时使用perfmon应用程序,以查看在线程执行I/O工作时分配了多少资源!即使这样做是错误的,您也会在每次绘画活动中重新下载内容。绘制处理程序不是执行此操作的地方,如果必须选择,我将在加载的事件中执行此操作。\u img不会等于下一个绘制事件的null。好的,我错过了,但仍然是绘制事件?在这次事件中没有理由这样做。您从不使用PaintEventArgs,这是进入事件的唯一原因。如果你做了一些事情,比如说;我可以同意,但DoSomethingWith也不使用参数。最后,您不能安全地执行异步绘制事件,即PaintEventArgs,因此,当您使用eMy时,将处理等待返回e,如果您使用eMy示例未使用PaintEventArgs,但您是对的,如果使用了,则不起作用。我按照你的建议改为使用Load。