Я занимаюсь разработкой программного обеспечения с использованием FANUC Robot Interface DLL.DLL содержит тип DataTable
, который необходимо обновлять (вызывая DataTable.Refresh()
) каждые 20 мс, чтобы получить новые данные от робота.Мне нужно сделать это в другом потоке, кроме основного, поэтому я создал BackgroundWorker
для вызова метода Refresh()
.
На ПК (PC_1), который я использую для разработки программного обеспечения, у меня естьсимулятор, который создает виртуального робота, с которым я могу протестировать свое программное обеспечение.Программное обеспечение работает с виртуальным роботом без каких-либо проблем.Однако, когда я перехожу на ПК (ПК_2), связанный с реальным роботом, я могу использовать только основной поток для вызова DataTable.Refresh()
, и метод, вызванный в BackgroundWorker
, вызовет следующее исключение:
System.InvalidCastException: 'Невозможно привести объект COM типа' System .__ ComObject 'к типу интерфейса' FRRJIf._DataTable '.Эта операция завершилась неудачно, поскольку вызов QueryInterface в компоненте COM для интерфейса с IID '{F7009573-2D48-4A59-BACC-356CAF720DF0}' завершился ошибкой из-за следующей ошибки: Ошибка загрузки библиотеки типов / DLL.(Исключение из HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)). '
Оба ПК имеют одинаковую версию DLL, но ПК_1 работает под управлением Win10, а ПК_2 работает под управлением Windows 7. Согласно сообщению об исключении, причинаПо-видимому, разница не между виртуальным и реальным роботом, а скорее в различиях в программной среде двух ПК.Тем не менее, я не могу ее решить.
Если связано, метод BackgroundWorker_DoWork
:
private DataTable _dataTable; //initialised from constructor
public BackgroundWorker DataTableBackgroundRefresher;
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
IsBusy = true;
var bgw = sender as BackgroundWorker;
try
{
while (!bgw.CancellationPending)
{
_dataTable.Refresh();
}
}
catch
{
IsBusy = false;
e.Cancel = true;
throw;
}
IsBusy = false;
e.Cancel = true;
}
Методы испытаний просто:
DataTable _dataTable; //initialised from Class Initilizer.
[TestMethod]
public async Task RefreshDataTable_mainThread()
{
_dataTable.Refresh();
}
[TestMethod]
public async Task RefreshDataTable_mainThread()
{
DataTableBackgroundRefresher.RunWorkerAsync();
}