0

我正在尝试使用 Flickr.net API 上传一些图像。图像已上传,但用户界面冻结。我已在后台工作人员中插入了上传代码

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    foreach (var item in imagelist)
    {
        flickr.UploadPicture(item, Path.GetFileName(item), null, null, true, false, true);
    }
    MessageBox.Show("Success");
}

flickr 对象是之前从另一个表单创建的,并传递给这个表单。if(worker.IsBusy==false){backgroundWorker1.RunWorkerAsync();}当一个按钮被点击时,我打电话给工人。

4

2 回答 2

2

造成这种情况的两个常见原因是,您的代码段太简短而无法缩小范围。首先是 ReportProgress 方法,事件处理程序在 UI 线程上运行。如果您过于频繁地调用它,那么 UI 线程可能会被调用请求淹没并花费太多时间来处理它们。它不再执行其常规职责,例如响应绘制请求和处理用户输入。因为一旦处理完调用请求,就会有另一个等待被调度。UI 线程实际上并没有被冻结,它看起来就是这样。净效果是一样的。您需要通过减慢工作人员的速度或减少调用 ReportProgress 的频率来修复它。

第二个原因是您的闪烁对象不是线程安全的,并且它本身确保它以线程安全的方式使用。通过自动编组从工作线程到 UI 线程的调用。这对于 COM 组件很常见,这种封送处理是 COM 的核心特性。同样,UI 线程实际上并没有被冻结,但它仍然不会处理绘画和输入,因为它正忙于上传照片。您需要通过在工作线程上创建闪烁对象来修复它。很有可能您无法使用 BackgroundWorker 执行此操作,因此此类组件通常需要一个 STA 线程来泵送消息循环。这需要 Thread.SetApartmentState() 和 Application.Run()。

于 2012-06-30T08:45:21.677 回答
0

如果您正在执行以下操作:

while(worker.IsBusy)
{
}

等待它完成,这将挂起,因为它将 UI 线程绑定在循环中,并且由于后台工作人员需要调用 UI 线程以安全地设置忙属性,因此存在死锁。

于 2012-06-30T08:09:38.560 回答