Исключение TargetInvocationException не было обработано в конце метода DoWork Backgroundworker.
Вот DoWork:
private void uploadWorker_DoWork(object sender, DoWorkEventArgs e)
{
uploadWorker.ReportProgress(20);
int tiffError = 0;
finalFiles = Directory.GetFiles(AppVars.FinalPolicyImagesFolder);
foreach (string file in finalFiles)
{
if (!file.EndsWith(".tiff"))
{
tiffError = 1;
break;
}
}
uploadWorker.ReportProgress(50);
if (tiffError == 1)
{
MessageBox.Show("There are files in this folder that are not .tiff. Please ensure only .tiff files are in this folder.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (finalFiles.Length == 0)
{
MessageBox.Show("There are no TIFF files to be uploaded. Please generate files first.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
pbUpload.Value = 0;
EnableAllButtons();
}
else
{
double count = finalFiles.Length;
int current = 0;
int pbValue = 0;
uploadWorker.ReportProgress(70);
foreach (string file in finalFiles)
{
current = current + 2;
if (file.Contains(".tiff") == true)
{
PolicyNumber = Path.GetFileName(file).Split('_')[0];
basePolicyNumber = PolicyNumber.Remove(PolicyNumber.Length - 2);
basePolicyNumber = basePolicyNumber + "00";
finalPolicyName = Path.GetFileName(file);
PolicyUUID = Transporter.GetPolicyUUID(AppVars.pxCentralRootURL, basePolicyNumber);
if (PolicyUUID == "")
{
MessageBox.Show("The InsightPolicyID for the policy you are trying to upload does not exist in ixLibrary. Please ensure the policy number is correct. If you are sure it should be in ixLibray, please contact IT.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
ixLibrarySourceFileURL = AppVars.ixLibraryPolicyAttachmentsURL + finalPolicyName;
UploadToixLibraryErrorCode = Transporter.UploadFileToixLibrary(AppVars.ixLibraryPolicyAttachmentsURL, file);
if (UploadToixLibraryErrorCode != 0)
{
MessageBox.Show("There was an error uploading the file to ixLibrary. Please contact IT about this problem.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
GeneratePayLoadErrorCode = Transformer.GeneratePayLoad(ixLibrarySourceFileURL, finalPolicyName);
if (GeneratePayLoadErrorCode != 0)
{
MessageBox.Show("There was an error generating the XML for pxCentral. Please contact IT about this problem.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
pxCentralPOSTErrorCode = Transporter.pxCentralPOST(AppVars.pxCentralRootURL + PolicyUUID, AppVars.pxCentralXMLPayloadFilePath);
pbValue = Convert.ToInt32(((current / count) * 30) + 70);
uploadWorker.ReportProgress(pbValue);
}
}
}
}
}
}
}
}
Как только он достигнет последнего}, я получаю TargetInvocationException - здесь была необработанная ошибка (см. Комментарий в коде):
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool createdNew = false;
Mutex mutex = new Mutex(true, "MyApplicationMutex", out createdNew);
if (createdNew == true)
{
//error happens here
Application.Run(new frmMain());
}
else
{
MessageBox.Show("The application is already running.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
Я не уверен, почему это случилось внезапно. Кто-нибудь знает почему?
Наконец, вот RunWorkerCompleted:
private void uploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
DeleteFinalFiles(finalFiles);
MessageBox.Show("Upload process complete.", "Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
EnableAllButtons();
}
4 ответа
Ты звонишь EnableAllButtons
в вашем DoWork
обработчик. это, по-видимому, меняет Enabled
состояние кнопок на форме. это недопустимо для любого другого потока, кроме потока пользовательского интерфейса. Вы должны сделать звонок EnableAllButtons
в вашем ProgressChanged
обработчик событий или в вашем RunWorkerCompleted
обработчик события. Вы также звоните ProgressBar.Value
в DoWork
с кодом pbUpload.Value = 0
,
Также вам следует позвонить MessageBox.Show
из вашего потока пользовательского интерфейса (т.е. в ProgressChanged
или же RunworkerCompleted
обработчик), так что MessageBox
могут быть связаны с вашей формой сообщения насосом правильно. Вы должны передать объект формы MessageBox.Show
чтобы связать окно сообщения с формой, чтобы вы не могли вывести форму на передний план, пока отображается окно сообщения. например:
MessageBox.Show(this,
"There are files in this folder that are not .tiff. Please ensure only .tiff files are in this folder.",
"Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
У меня была точно такая же проблема с исключением TargetInvocation, возникшим после завершения фонового процесса. Внутри события backgroundWorker ProgressChanges у меня есть ссылки на элементы управления, как показано ниже`private void m_oWorker_ProgressChanged(отправитель объекта, ProgressChangedEventArgs e) {
// This function fires on the UI thread so it's safe to edit
// the UI control directly, no funny business with Control.Invoke :)
CurrentState state =
(CurrentState)e.UserState;
txtProgress.Text = state.CrawlStatus;
lblStatus2.Text = state.sStatus;
txtItemsStored.Text = state.TotItems.ToString() + " items";
txtLastRunTime.Text = state.MostRecentGatherDate.ToString();
AppNameKey.SetValue("LastCrawlTime", txtLastRunTime.Text);
}`
Событие DoWork читает из элемента управления
private void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
{
DateTime LastCrawlTime;
try
{
LastCrawlTime = Convert.ToDateTime(txtLastRunTime.Text);
if (lblStatus2.Text != "Status: Running" || (!cmdRunNow.Enabled && cmdStopRun.Enabled)) // run is not currently running or cmdRunNow clicked
{
//lblStatus2.Text = "Status: Running";
GetUpdated(LastCrawlTime,e);
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
Событие RunWorkedrCompleted записывает в элемент управления:
void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
lblStatus2.Text = "Status: Stopped";
cmdStopRun.Enabled = false;
}
// Check to see if an error occurred in the background process.
else if (e.Error != null)
{
lblStatus2.Text = "Fatal Error while processing.";
}
else
{
// Everything completed normally.
//CurrentState state = (CurrentState)e.UserState;
lblStatus2.Text = "Status: Finished";
}
}
Ни один из них не вызвал проблем. Причиной проблемы была попытка ссылки на e.UserState в событии RunWorker_Completed (закомментировано выше).
В WinForms вы должны иметь доступ только к элементу управления в потоке, который создал элемент управления. Ваш обработчик событий DoWork не работает в потоке, который создал форму (что, разумеется, является точкой). Следовательно, вы не должны получать доступ ни к одному из элементов управления в форме в обработчике DoWork. Это может привести к непредсказуемым результатам.
Я разобрался в проблеме.
Индикатор выполнения превышал максимально допустимое значение (из 100).
Проблема заключалась в том, что в коде я увеличивал индикатор выполнения как таковой:
current = current + 2;
Я заменил его на:
current++;
Причина, по которой я увеличивал на 2, была просто для целей тестирования.