비 관리 C++ 루틴으로 작성된 외부 DLL에서 수행되는 취소 가능한 작업을 시작하는 C# 비동기 코드를 수정하려고합니다.관리되지 않는 C++ 외부 루틴을 실행하는 작업을 취소하는 방법
사용자 대리인이 관리되지 않는 외부 C++ 루틴을 호출하는 경우 생성시 작업에 전달 된 취소 토큰을 사용하여 작업을 취소하는 방법이 있습니까?
내가 알다시피, 작업 취소에는 사용자 대리인과 취소를 요청한 코드 간의 협력이 필요합니다. 성공적인 취소에는 CancellationTokenSource.Cancel 메서드를 호출하는 요청 코드와 사용자가 취소 요청이 제기 된 것을 알았을 때 대리자에서 단순히 반환하여 (CancellationToken.IsCancellationRequested를 폴링하여) 작업을시기 적절하게 종료하는 대리자가 필요합니다. 메서드)를 사용하거나 CancellationToken.ThrowIfCancellationRequested 메서드를 사용하여 OperationCanceledException을 throw합니다. (http://msdn.microsoft.com/en-us/library/dd997396%28v=vs.110%29.aspx)
이 두 가지 방법은 CancellationToken을 매개 변수로 받고 일정한 간격으로 IsCancellationRequested 및/또는 ThrowIfCancellationRequested 메서드를 호출하여 사용자 대리자에 의해 실행되는 관리되지 않는 C++ 루틴이 협조하는 방식입니다.
관리되지 않는 외부 C++ 루틴에서 그렇게 할 수 있습니까?
그렇지 않은 경우 요청 코드에 의해 취소가 요청 될 때 사용자 위임을 실행하는 작업이 강제 종료되는 방법 (비 관리 C++ 루틴 실행)이 있습니까?
다음은 C++ 비 관리 코드 파트에서 사용자 대리인에 의해 수행 된 작업을 취소 할 수 있도록 해결하려는 혼합 C#/C++ Cli/비 관리 C++ 코드의 예 (추출)입니다. :
FrmDemo.cs : ----------------------------------------- --------------------------------
public class FrmDemo : Form
{
private CliClass m_CliObject;
private System.Threading.CancellationTokenSource m_Cts;
private System.Threading.CancellationToken m_Ct;
private void FrmDemo_Load(object sender, EventArgs e)
{
// Creating the external CliObject:
this.m_CliObject = new NSDemo.CliClass();
...
}
// Event handler of the button starting the cancelable asynchrone operation:
private async void btnStart_Click(object sender, EventArgs e)
{
m_Cts = new System.Threading.CancellationTokenSource();
m_Ct = m_Cts.Token;
await Task.Factory.StartNew(() =>
{
// Launching a cancelable operation performed by a managed C++Cli Object :
this.m_CliObject.DoSomething(); // How to eventually pass the CancellationToken m_ct to the m_CliObject ?
}, m_ct);
...
}
//Event handler of the cancel button:
private void btnCancel_Click(object sender, EventArgs e)
{
// Requesting cancellation:
m_Cts.Cancel();
// (Or alternatively, how to eventually force the termination of the async Task without collaboration from it ?)
}
CliClass.h : ------- ----------------------------------------------
#include "DemoCore.h"
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace cli;
namespace NSDemo
{
public ref class CliClass
{
public:
CliClass();
~CliClass();
void DoSomething()
{
// Performing the operation in the unmanaged coreObject:
_coreObject->DoSomething();
}
private:
UNSDemo::CoreClass *_coreObject;
bool _disposed;
};
}
CliClass.cpp : ------------------------------------------
namespace NSDemo
{
CliClass::CliClass()
{
_coreObject = new UNSDemo::CoreClass(...);
....
}
CliClass::~CliClass()
{
if (_disposed)
return;
if (_coreObject != nullptr) {
delete _coreObject;
_coreObject = nullptr;
}
_disposed = true;
GC::SuppressFinalize(this);
}
CoreClass.h-----------------------------------------------------------------
namespace UNSDemo {
class __declspec(dllexport) CoreClass {
public:
ScanningCore();
~ScanningCore();
void DoSomething();
private:
...
};
}
CoreClass.cpp : ------------------------------------------ ----------------------------------
#include "CoreClass.h"
namespace UNSDemo {
CoreClass::CoreClass()
{
...
}
CoreClass::~CoreClass()
{
...
}
// Method actually performing the cancelable operation:
void CoreClass::DoSomething()
{
// Main loop of the unmanaged cancelable operation:
while (...) {
...
// How to check the cancellation request from here ? (How to access the CancellationToken ?)
// and if cancellation is requested, how to eventually throw the OperationCanceledException ?
}
}
}
감사합니다.